Class: Dolibarr::Api::Connection

Inherits:
Object
  • Object
show all
Defined in:
lib/dolibarr-api/connection.rb

Overview

The single HTTP choke-point. Every operation goes through call.

Instance Method Summary collapse

Constructor Details

#initialize(configuration) ⇒ Connection

Returns a new instance of Connection.



6
7
8
9
10
11
12
13
14
15
16
# File 'lib/dolibarr-api/connection.rb', line 6

def initialize(configuration)
  @configuration = configuration
  # Force a trailing slash so a base_url that itself carries a path prefix
  # (e.g. "https://api.ovh.com/1.0") is preserved: request paths are made
  # relative (their leading slash is stripped in #call) and resolved against it.
  base = configuration.base_url
  base += '/' unless base.end_with?('/')
  @faraday = Faraday.new(url: base) do |conn|
    configuration.configure_faraday(conn)
  end
end

Instance Method Details

#call(method, path, type: nil, auth: [], query: {}, headers: {}, body: nil, form: nil) ⇒ Object

body (JSON) and form (urlencoded/multipart) are mutually exclusive -- an operation has either a request body or form params, never both.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/dolibarr-api/connection.rb', line 20

def call(method, path, type: nil, auth: [], query: {}, headers: {}, body: nil, form: nil)
  # Faraday's `run_request` only accepts lowercase method symbols; api.mustache
  # emits the readable uppercase form (e.g. `:GET`), so normalize it here.
  method = method.to_s.downcase.to_sym
  # Make the path relative so Faraday resolves it against the (slash-terminated)
  # base_url without discarding any base path prefix.
  path = path.sub(%r{\A/+}, '')
  request_headers = merge_headers(headers)
  request_query = query.compact.transform_keys(&:to_s)
  # Only the auth schemes the operation actually declares are applied, so credentials
  # never leak to endpoints with `security: []` nor stack conflicting Authorization
  # headers on operations that accept only one of several schemes.
  @configuration.apply_auth(request_headers, request_query, auth)
  request_body =
    if form
      wrap_form(form)
    else
      # Pin the content type ourselves so the `:multipart`/`:url_encoded` request
      # middlewares (registered ahead of `:json` in Configuration#configure_faraday
      # so form calls can be encoded before `:json` sees them) do not mistake a
      # plain JSON Hash/Array body for a form payload -- both only skip a request
      # once its Content-Type is set to something other than what they handle.
      request_headers['Content-Type'] ||= 'application/json' unless body.nil?
      serialize_body(body)
    end

  response = @faraday.run_request(method, path, request_body, request_headers) do |req|
    req.params.update(encode_query(request_query))
  end
  raise ApiError.from(response) unless response.success?

  Response.new(data: deserialize(response.body, type), status: response.status, headers: response.headers)
rescue Faraday::Error => e
  # Ruby sets #cause automatically to `e` when raising inside a rescue block.
  raise ApiError, e.message
end