Class: Pluggy::APIRequestor

Inherits:
Object
  • Object
show all
Defined in:
lib/pluggy/api_requestor.rb

Overview

Builds, sends and interprets every HTTP request.

Owns three things worth understanding: the apiKey lifecycle, the 403 fork, and the retry policy.

Constant Summary collapse

IDEMPOTENT_METHODS =
%i[get head delete].freeze
RETRYABLE_POST_PATHS =

POST endpoints that are safe to retry because they create no durable resource. POST /items is NOT here on purpose: the API offers no Idempotency-Key, so retrying it risks opening a duplicate bank connection, which is user-visible and awkward to undo.

["/auth", "/connect_token"].freeze
RETRY_STATUSES =
[429, 500, 502, 503, 504].freeze
RETRY_ERRORS =
[
  Errno::ECONNRESET, Errno::ECONNREFUSED, Errno::EPIPE, Errno::EHOSTUNREACH,
  Errno::ETIMEDOUT, Net::OpenTimeout, Net::ReadTimeout, Net::WriteTimeout,
  EOFError, SocketError, IOError, OpenSSL::SSL::SSLError
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config, credentials = nil) ⇒ APIRequestor

Returns a new instance of APIRequestor.



33
34
35
36
# File 'lib/pluggy/api_requestor.rb', line 33

def initialize(config, credentials = nil)
  @config = config
  @credentials = credentials || CredentialStore.new(config)
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



31
32
33
# File 'lib/pluggy/api_requestor.rb', line 31

def config
  @config
end

#credentialsObject (readonly)

Returns the value of attribute credentials.



31
32
33
# File 'lib/pluggy/api_requestor.rb', line 31

def credentials
  @credentials
end

Instance Method Details

#execute_unauthenticated(method, path, body: nil) ⇒ Object

POST /auth is the only unauthenticated operation in the API.



53
54
55
# File 'lib/pluggy/api_requestor.rb', line 53

def execute_unauthenticated(method, path, body: nil)
  execute(method, path, body, authenticated: false)
end

#list(path, params:, klass:, client:, paginated: false) ⇒ Object



57
58
59
60
61
62
63
# File 'lib/pluggy/api_requestor.rb', line 57

def list(path, params:, klass:, client:, paginated: false)
  Lists.wrap(
    request(:get, path, params: params),
    klass: klass, requestor: self, path: path,
    filters: params || {}, client: client, paginated: paginated
  )
end

#list_raw(path_with_query, klass:, client:) ⇒ Object



65
66
67
68
69
70
# File 'lib/pluggy/api_requestor.rb', line 65

def list_raw(path_with_query, klass:, client:)
  Lists.wrap(
    request_raw(:get, path_with_query),
    klass: klass, requestor: self, path: path_with_query.split("?").first, client: client
  )
end

#request(method, path, params: nil, body: nil, opaque_body_keys: []) ⇒ Object

--- surface used by services ------------------------------------------



40
41
42
43
44
# File 'lib/pluggy/api_requestor.rb', line 40

def request(method, path, params: nil, body: nil, opaque_body_keys: [])
  url = build_path(path, params)
  payload = body && Util.encode_body(body, opaque: opaque_body_keys)
  execute(method, url, payload, authenticated: true)
end

#request_raw(method, path_with_query) ⇒ Object

For cursor pagination: path_with_query already carries the server's "?..." string, so no query building happens at all.



48
49
50
# File 'lib/pluggy/api_requestor.rb', line 48

def request_raw(method, path_with_query)
  execute(method, path_with_query, nil, authenticated: true)
end