Class: CongregaPlenum::Client

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/client.rb,
sig/congrega_plenum.rbs

Overview

HTTP client responsible for talking to the Câmara API endpoints and dealing with retries, pagination and response parsing.

All methods are thread-safe because the heavy collaborators (HttpAdapter, RetryPolicy and ResponseHandler) are stateless.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeClient

Returns a new instance of Client.



14
15
16
17
18
19
# File 'lib/client.rb', line 14

def initialize
  configuration = CongregaPlenum.configuration
  @http_adapter = HttpAdapter.new(configuration: configuration)
  @retry_policy = RetryPolicy.new(configuration: configuration)
  @response_handler = ResponseHandler.new
end

Instance Attribute Details

#http_adapterHttpAdapter (readonly)

Returns the value of attribute http_adapter.

Returns:



12
13
14
# File 'lib/client.rb', line 12

def http_adapter
  @http_adapter
end

#response_handlerResponseHandler (readonly)

Returns the value of attribute response_handler.

Returns:



12
13
14
# File 'lib/client.rb', line 12

def response_handler
  @response_handler
end

#retry_policyRetryPolicy (readonly)

Returns the value of attribute retry_policy.

Returns:



12
13
14
# File 'lib/client.rb', line 12

def retry_policy
  @retry_policy
end

Class Method Details

.instanceClient

Returns:



73
# File 'sig/congrega_plenum.rbs', line 73

def self.instance: () -> Client

Instance Method Details

#apply_rate_limit_delayvoid

This method returns an undefined value.

Sleep between page fetches to respect the rate limit exposed by the API. This is configurable because not every consumer has the same tolerance.



76
77
78
79
80
# File 'lib/client.rb', line 76

def apply_rate_limit_delay
  delay = configuration.rate_limit_delay

  sleep(delay) if delay.positive?
end

#build_url(endpoint, params = {}) ⇒ String

Builds the full URL pointing to the Câmara API, ensuring formato=json is present.

Parameters:

  • endpoint (String)
  • params (Hash) (defaults to: {})
  • (String)
  • (params_hash)

Returns:

  • (String)


93
94
95
96
97
98
99
100
101
102
103
# File 'lib/client.rb', line 93

def build_url(endpoint, params = {})
  uri = URI("#{configuration.base_url}/#{endpoint.gsub(%r{^/}, '')}")

  # Ensure formato=json is always present
  normalized_params = params.transform_keys(&:to_sym)
  normalized_params[:formato] ||= 'json'

  uri.query = URI.encode_www_form(normalized_params)

  uri.to_s
end

#configurationConfiguration

Returns:



105
106
107
# File 'lib/client.rb', line 105

def configuration
  CongregaPlenum.configuration
end

#each_response_page(endpoint, params) {|arg0| ... } ⇒ void

This method returns an undefined value.

Parameters:

  • (String)
  • (params_hash)

Yields:

Yield Parameters:

  • arg0 (payload_list)

Yield Returns:

  • (void)


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/client.rb', line 49

def each_response_page(endpoint, params)
  page = 1

  loop do
    response = request_page(endpoint, params, page)
    data = response.fetch('dados', [])
    break if data.empty?

    yield(data)
    break unless next_page?(response)

    page += 1
    apply_rate_limit_delay
  end
end

#execute_request(url) ⇒ payload_hash

Parameters:

  • (String)

Returns:

  • (payload_hash)


82
83
84
85
86
# File 'lib/client.rb', line 82

def execute_request(url)
  response = http_adapter.get(url)

  response_handler.handle(response, url)
end

#get(endpoint, params = {}) ⇒ Hash

Performs a single HTTP GET to the given endpoint and returns the parsed JSON body.

Parameters:

  • endpoint (String)

    the relative path (e.g. deputados)

  • params (Hash) (defaults to: {})

    query parameters merged into the request

  • (String)
  • (params_hash)

Returns:

  • (Hash)

    parsed response body



27
28
29
30
31
# File 'lib/client.rb', line 27

def get(endpoint, params = {})
  url = build_url(endpoint, params)

  retry_policy.with_retries(url) { execute_request(url) }
end

#get_paginated(endpoint, params = {}) ⇒ Array<Hash>

Retrieves all pages for an endpoint, flattening the dados payloads into a single array. Automatically respects the configured rate limit delay.

Parameters:

  • endpoint (String)
  • params (Hash) (defaults to: {})
  • (String)
  • (params_hash)

Returns:

  • (Array<Hash>)


39
40
41
42
43
44
45
# File 'lib/client.rb', line 39

def get_paginated(endpoint, params = {})
  # @type var results: Array[Hash[String, untyped]]
  results = []
  each_response_page(endpoint, params) { |page_data| results.concat(page_data) }

  results
end

#next_page?(response) ⇒ Boolean

Parameters:

  • (payload_hash)

Returns:

  • (Boolean)


70
71
72
# File 'lib/client.rb', line 70

def next_page?(response)
  response.fetch('links', []).any? { |link| link['rel'] == 'next' }
end

#request_page(endpoint, params, page) ⇒ payload_hash

Fetches a single page enforcing formato=json and the requested page index.

Parameters:

  • (String)
  • (params_hash)
  • (Integer)

Returns:

  • (payload_hash)


66
67
68
# File 'lib/client.rb', line 66

def request_page(endpoint, params, page)
  get(endpoint, params.merge(pagina: page, formato: 'json'))
end