Module: ActiveCall::Api
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/active_call/api/version.rb,
lib/active_call/api.rb
Defined Under Namespace
Modules: Attributes
Constant Summary collapse
- VERSION =
'0.1.5'
Instance Method Summary collapse
- #bad_gateway? ⇒ Boolean
-
#bad_request? ⇒ Boolean
The methods below determine what type of error gets added to the errors object.
- #conflict? ⇒ Boolean
-
#connection ⇒ Object
Subclasses must implement a ‘connection` method to hold a `Faraday::Connection` object.
- #forbidden? ⇒ Boolean
- #gateway_timeout? ⇒ Boolean
- #gone? ⇒ Boolean
- #internal_server_error? ⇒ Boolean
- #not_acceptable? ⇒ Boolean
- #not_found? ⇒ Boolean
- #not_implemented? ⇒ Boolean
- #proxy_authentication_required? ⇒ Boolean
- #request_timeout? ⇒ Boolean
- #service_unavailable? ⇒ Boolean
- #too_many_requests? ⇒ Boolean
- #unauthorized? ⇒ Boolean
- #unprocessable_entity? ⇒ Boolean
Instance Method Details
#bad_gateway? ⇒ Boolean
295 296 297 |
# File 'lib/active_call/api.rb', line 295 def bad_gateway? response.status == 502 end |
#bad_request? ⇒ Boolean
The methods below determine what type of error gets added to the errors object.
service.errors # => #<ActiveModel::Errors [#<ActiveModel::Error attribute=base, type=bad_request, options={}>]>
When using ‘.call!`, they map to the `exception_mapping` above, so `bad_request?` maps to `bad_request`.
exception.errors # => #<ActiveModel::Errors [#<ActiveModel::Error attribute=base, type=bad_request, options={}>]>
These methods can be overridden to add more rules when an API does not respond with the relevant HTTP status code.
A common occurrence is when an API returns an HTTP status code of 400 with an error message in the body for anything related to client errors, sometimes even for a resource that could not be found.
It is not required to override any of these methods since all 4xx and 5xx errors add a ‘client_error` or `server_error` type to the errors object, respectively.
While not required, handling specific errors based on their actual meaning makes for a happier development experience.
You have access to the full ‘Farady::Response` object set to the `response` attribute, so you can use `response.status` and `response.body` to determine the type of error.
Perhaps the API does not always respond with a 422 HTTP status code for unprocessable entity requests or a 404 HTTP status for resources not found.
class YourGem::BaseService < ActiveCall::Base
...
def not_found?
response.status == 404 || (response.status == 400 && response.body['error_code'] == 'not_found')
end
def unprocessable_entity?
response.status == 422 || (response.status == 400 && response.body['error_code'] == 'not_processable')
end
243 244 245 |
# File 'lib/active_call/api.rb', line 243 def bad_request? response.status == 400 end |
#conflict? ⇒ Boolean
271 272 273 |
# File 'lib/active_call/api.rb', line 271 def conflict? response.status == 409 end |
#connection ⇒ Object
Subclasses must implement a ‘connection` method to hold a `Faraday::Connection` object.
This connection instance will then be used in the ‘call` methods of the individual service objects.
Examples
class YourGem::BaseService < ActiveCall::Base
config_accessor :api_key, default: ENV['API_KEY'], instance_writer: false
config_accessor :logger, default: Logger.new($stdout), instance_writer: false
def connection
@_connection ||= Faraday.new do |conn|
conn.url_prefix = 'https://example.com/api/v1'
conn.request :authorization, 'X-API-Key', api_key
conn.request :json
conn.response :json
conn.response :logger, logger, formatter: Faraday::Logging::ColorFormatter, prefix: { request: 'YourGem', response: 'YourGem' } do |logger|
logger.filter(/(Authorization:).*"(.+)."/i, '\1 [FILTERED]')
end
conn.adapter Faraday.default_adapter
end
end
You can now create a REST API service object like so.
class YourGem::SomeResource::UpdateService < YourGem::BaseService
attr_reader :id, :first_name, :last_name
validates :id, :first_name, :last_name, presence: true
def initialize(id:, first_name:, last_name:)
@id = id
@first_name = first_name
@last_name = last_name
end
# PUT /api/v1/someresource/:id
def call
connection.put("someresource/#{id}", first_name: first_name, last_name: last_name)
end
end
203 204 205 |
# File 'lib/active_call/api.rb', line 203 def connection raise NotImplementedError, 'Subclasses must implement a connection method. Must return a Faraday.new object.' end |
#forbidden? ⇒ Boolean
251 252 253 |
# File 'lib/active_call/api.rb', line 251 def forbidden? response.status == 403 end |
#gateway_timeout? ⇒ Boolean
303 304 305 |
# File 'lib/active_call/api.rb', line 303 def gateway_timeout? response.status == 504 end |
#gone? ⇒ Boolean
275 276 277 |
# File 'lib/active_call/api.rb', line 275 def gone? response.status == 410 end |
#internal_server_error? ⇒ Boolean
287 288 289 |
# File 'lib/active_call/api.rb', line 287 def internal_server_error? response.status == 500 end |
#not_acceptable? ⇒ Boolean
259 260 261 |
# File 'lib/active_call/api.rb', line 259 def not_acceptable? response.status == 406 end |
#not_found? ⇒ Boolean
255 256 257 |
# File 'lib/active_call/api.rb', line 255 def not_found? response.status == 404 end |
#not_implemented? ⇒ Boolean
291 292 293 |
# File 'lib/active_call/api.rb', line 291 def not_implemented? response.status == 501 end |
#proxy_authentication_required? ⇒ Boolean
263 264 265 |
# File 'lib/active_call/api.rb', line 263 def proxy_authentication_required? response.status == 407 end |
#request_timeout? ⇒ Boolean
267 268 269 |
# File 'lib/active_call/api.rb', line 267 def request_timeout? response.status == 408 end |
#service_unavailable? ⇒ Boolean
299 300 301 |
# File 'lib/active_call/api.rb', line 299 def service_unavailable? response.status == 503 end |
#too_many_requests? ⇒ Boolean
283 284 285 |
# File 'lib/active_call/api.rb', line 283 def too_many_requests? response.status == 429 end |
#unauthorized? ⇒ Boolean
247 248 249 |
# File 'lib/active_call/api.rb', line 247 def response.status == 401 end |
#unprocessable_entity? ⇒ Boolean
279 280 281 |
# File 'lib/active_call/api.rb', line 279 def unprocessable_entity? response.status == 422 end |