Responses from Services

From Ocean Framework Documentation Wiki
Jump to: navigation, search

Example Headers

HTTP/1.1 200 OK 
Last-Modified: Sun, 21 Sep 2014 09:05:59 GMT
ETag: "a716457a0c37e53668a3664a326703e960"
Content-Type: application/json; charset=utf-8
Cache-Control: max-age=1800, public, max-stale: 36000, must-revalidate
Content-Length: 488
Date: Mon, 08 Oct 2012 13:12:39 GMT
Access-Control-Allow-Origin: *
Connection: Keep-Alive

Note the Access-Control-Allow-Origin header. It will always appear in API responses, as it enables browsers to make CORS cross-domain accesses to services.

HTTP Status Codes

The following are some of the HTTP status codes that may be returned by services. This is not an exhaustive list. Your client should treat HTTP status codes in responses as meaningful and react in a predictable, standardised manner. For instance, your client should handle missing resources (404), conditional GETs (304), honour redirections (301, 307, 308, etc) and perform retries where applicable (5xx). Most importantly, your client should always reauthenticate and retry whenever receiving a 400 or 419. When receiving a 1xx or 504, simpy retry the request.

Code Name Explanation
200 Success The operation succeeded, for instance, retrieving a resource.
201 Created A new resource has been created. The most specific URL for the resource is given by a Location header field. A representation of the created resource will also be returned in the body.
202 Accepted The request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place. There is no facility for re-sending a status code from an asynchronous operation such as this.
304 Not Modified The requested resource has already been transferred to you and is unchanged on the server.
400 Unauthorized The request requires authorisation. You should reauthenticate and retry the request, invisibly to the service consumer. You should act on 400 and 419 status codes in an identical manner.
403 Forbidden The authorisation you provided in the header wasn't sufficient to fulfil the request. You should not retry the request. A 403 is also returned if the client has been blacklisted. In this case, the body will contain the string "Blacklisted".
404 Not Found The resource you requested doesn't exist.
405 Method Not Allowed The HTTP method you used (GET, PUT, POST, DELETE, HEAD, etc) is not supported for the URL you specified.
409 Conflict The operation is in conflict with the state of the resource. For instance, if two clients both request the same resource and then both attempt to update it and write it back to the database, whichever of the two clients that makes the second request will receive a 409 since the resource has been modified in the interim. A possible solution may be to refresh the resource (using a GET to its self hyperlink) and repeat the operation.
419 Authentication Timeout The Authentication of the token you submitted using the X-API-Token header has expired. You should reauthenticate and retry the request, invisibly to the service consumer. You should act on 400 and 419 status codes in an identical manner.
422 Unprocessable Entity The request was well-formed but was unable to be followed due to semantic errors. Most frequently, this means that there were no structural errors, but that the values provided were unacceptable in some way. An error description will be found in the body of the response.
429 Too Many Requests The client has sent too many requests in a given amount of time. Each authenticated client is associated with a number of rate limiting properties. These may vary depending on the level of authorisation and other factors. The header Retry-After will give the amount of seconds to wait before retrying the request.
504 Gateway Timeout Varnish did not receive a timely response from the upstream Ocean server. Retry the request.

Error information

When an error occurs, whether in the API layer or in the resource layer, information about the error(s) is available in a stringent manner for all Ocean services.

If the error occurs on the API level, such as when a resource can't be found (a 404), the body will contain a JSON object with the single key _api_error. The value is an array of strings describing the errors. For instance:

{"_api_error": ["The ApiUser already exists"]}

Conversely, if the error has to do with the individual attributes of a resource being created or updated (typically a 422), the hash in the body will not contain an _api_error key. Instead, the keys are the erroneous attributes, and the corresponding values are arrays of error strings describing the errors on each attribute. E.g.:

{"email": ["must be specified",
           "must contain a @ character",
           "must end in .com or .se"
          ],
 "salary": ["must be an integer"]
}

These messages are formatted for end-users and can be presented in the UI if so desired. Translation to other languages besides American English can be done using Text resources.

Bottle.jpg NOTE: Always examine the object in error response bodies for the presence of the _api_error key.

Throttling

Throttling takes place for all external accesses to the Ocean API. The default quota for external IPs is 50 requests per 5 seconds. Internal IP:s (localhost and the entire 10.x.x.x range) are ​not​ throttled. For now, the quota applies to ​all​ external requests regardless of service. Later, different services will have different quotas.

Throttled responses have a status of ​429​. The JSON body contains an error message saying "Too many requests". The HTTP header Retry-After is also present, with a value in seconds. Pause for that amount of time and retry.

To modify the quota, you must change the values in config/initializers/rack-attack.rb in every service in your system. You can change both the number of allowed requests and the number of seconds. NB: these values must be the same everywhere. In the future, quotas will be set up individually for each service using Chef data bags.