Class: Anypost::HttpClient Private
- Inherits:
-
Object
- Object
- Anypost::HttpClient
- Defined in:
- lib/anypost/http_client.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
Owns a Faraday connection and implements the request loop: header assembly, retries with full-jitter backoff, idempotency keys, and error mapping.
Constant Summary collapse
- RETRYABLE_STATUS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
[429, 502, 503].freeze
- MAX_BACKOFF_SECONDS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
8.0- BASE_BACKOFF_SECONDS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
0.5
Class Method Summary collapse
- .user_agent ⇒ Object private
Instance Method Summary collapse
-
#initialize(api_key:, base_url:, timeout:, max_retries:, default_headers: {}, connection: nil, sleeper: nil, jitter: nil) ⇒ HttpClient
constructor
private
A new instance of HttpClient.
-
#request(method, path, body: nil, query: nil, idempotent: false, idempotency_key: nil, max_retries: nil, extra_headers: nil) ⇒ Object
private
Perform a request and return the decoded JSON body.
Constructor Details
#initialize(api_key:, base_url:, timeout:, max_retries:, default_headers: {}, connection: nil, sleeper: nil, jitter: nil) ⇒ HttpClient
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of HttpClient.
19 20 21 22 23 24 25 26 27 |
# File 'lib/anypost/http_client.rb', line 19 def initialize(api_key:, base_url:, timeout:, max_retries:, default_headers: {}, connection: nil, sleeper: nil, jitter: nil) @api_key = api_key @max_retries = max_retries @default_headers = default_headers @connection = connection || build_connection(base_url, timeout) @sleeper = sleeper || ->(seconds) { sleep(seconds) if seconds.positive? } @jitter = jitter || -> { rand } end |
Class Method Details
Instance Method Details
#request(method, path, body: nil, query: nil, idempotent: false, idempotency_key: nil, max_retries: nil, extra_headers: nil) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Perform a request and return the decoded JSON body.
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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/anypost/http_client.rb', line 30 def request(method, path, body: nil, query: nil, idempotent: false, idempotency_key: nil, max_retries: nil, extra_headers: nil) retries = max_retries.nil? ? @max_retries : max_retries headers = build_headers( has_body: !body.nil?, idempotent: idempotent, idempotency_key: idempotency_key, max_retries: retries, extra_headers: extra_headers ) payload = body.nil? ? nil : JSON.generate(body) params = clean_query(query) relative = path.sub(%r{\A/+}, "") attempt = 0 loop do begin response = @connection.run_request(method, relative, payload, headers) do |req| req.params.update(params) unless params.empty? end rescue Faraday::TimeoutError, Faraday::ConnectionFailed => e raise APIConnectionError.new((e), cause: e) unless attempt < retries @sleeper.call(backoff(attempt, nil)) attempt += 1 next end status = response.status return decode(response) if status >= 200 && status < 300 if RETRYABLE_STATUS.include?(status) && attempt < retries @sleeper.call(backoff(attempt, response.headers)) attempt += 1 next end raise Errors.from_response(status, decode(response), response.headers) end end |