Class: AureEx::HttpTransport

Inherits:
Object
  • Object
show all
Defined in:
lib/aure_ex/client.rb

Overview

Transporte HTTP autenticado com retry em 429.

Instance Method Summary collapse

Constructor Details

#initialize(api_key:, api_secret:, base_url:, max_retries: 2) ⇒ HttpTransport

Returns a new instance of HttpTransport.



22
23
24
25
26
27
# File 'lib/aure_ex/client.rb', line 22

def initialize(api_key:, api_secret:, base_url:, max_retries: 2)
  @api_key = api_key
  @api_secret = api_secret
  @base_url = base_url.sub(%r{/\z}, '')
  @max_retries = max_retries
end

Instance Method Details

#request(method, path, body: nil, extra_headers: {}) ⇒ Object

Executa requisição autenticada e desempacota o envelope data.



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
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/aure_ex/client.rb', line 30

def request(method, path, body: nil, extra_headers: {})
  url = URI("#{@base_url}/#{path.sub(%r{\A/}, '')}")
  attempt = 0

  loop do
    attempt += 1
    http = Net::HTTP.new(url.host, url.port)
    http.use_ssl = url.scheme == 'https'

    verb = method.to_s.upcase
    request_class = {
      'GET' => Net::HTTP::Get,
      'POST' => Net::HTTP::Post,
      'PUT' => Net::HTTP::Put,
      'PATCH' => Net::HTTP::Patch,
      'DELETE' => Net::HTTP::Delete
    }.fetch(verb)

    request = request_class.new(url)
    request['X-Api-Key'] = @api_key
    request['X-Api-Secret'] = @api_secret
    request['Accept'] = 'application/json'
    request['Content-Type'] = 'application/json'
    extra_headers.each { |key, value| request[key] = value }
    request.body = JSON.generate(body) unless body.nil?

    response = http.request(request)
    status = response.code.to_i
    raw = response.body.to_s
    decoded = raw.empty? ? nil : JSON.parse(raw)

    if status == 429 && attempt <= @max_retries + 1
      sleep([1, (response['Retry-After'] || '1').to_i].max)
      next
    end

    if status >= 400
      error = decoded.is_a?(Hash) ? decoded['error'] : nil
      message = error.is_a?(Hash) ? (error['message'] || 'Request failed.') : 'Request failed.'
      raise Error.new(
        message.to_s,
        code: error.is_a?(Hash) ? error['code'] : nil,
        details: error.is_a?(Hash) ? error['details'] : nil,
        status_code: status
      )
    end

    return decoded['data'] if decoded.is_a?(Hash) && decoded.key?('data')

    return decoded
  end
end