For every operation you have to describe all expected responses and how they should be processed.
Use the response
method with expected http response status(es):
class CatsAPI < Evil::Client
response 200, 201, 404, 422, 500
end
These definitions are inherited by all subscopes/operations. You can reload them later for every separate status. The definition tells a client to accept responses with given statuses, and to return rack-compatible response as is.
Using a block, you can handle the response in a way you need. For example, the following code will extract and parse json body only.
response 200 do |(_status, _headers, *body)|
JSON.parse(body.first) if body.any?
end
Remember that in rack responses body is always wrapped to array (enumerable structure).
Do you best to either wrap a response to your domain model, or raise a specific exception:
response 200 do |(_status, _headers, *body)|
Cat.new(JSON.parse(body.first)) if body.any?
end
response 400, 422 do |_status, *|
raise "#{status}: Record invalid"
end
When you use client-specific middleware, the response
block will receive the result already processed by the whole middleware stack. The helper will serve a final step of its handling. Its result wouldn't be processed further in any way.
If a remote API will respond with a status, not defined for the operation, the Evil::Client::ResponseError
will be risen. The exception carries both the response, and all its parts (status, headers, and body).