There’s plenty of articles out there on how to build the perfect REST API, so I am not going to go into that. This article is all about what to think about when you’re building the perfect client for a REST API. What you’re being served is clearly important – but how you use that information is 50% of the problem – and it needs to be done correctly.
API designers can spend a lot of time ensuring that their responses to you are perfectly well formed and self describing – but unless you pay attention to what it is that those messages are telling you, all that information is simply being thrown away.
The very first thing your HTTP client will send to the server is the Request headers. Within that request, more often than not, you will send the Accept header and a list of media types that your client can support – and the order of preference within which you would like to see them. Chrome 20.0.1132.47 sends the following Accept header.
Obviously this is a web browser, so it’s preference is going to be for text/html or application/xhtml+xml. Failing that, we can also take application/xml. If the server still can’t handle the request – then we’ll take anything at all (*/*).
The web server will make a decision based on what your client has asked for. From that point on one of 3 things can happen. 1) You get back one of the media formats that you asked for. 2) You receive a 406 response (Not Acceptable). 3) You get back something you didn’t ask for at all (this is allowed as per RFC2616 – the server SHOULD only respond with a 406).
This means that unless you’re explicitly checking what the response is after the request comes back – you could find yourself only assuming that the server is behaving as you think it is.
The Accept header becomes very useful when you separate out a normal response from an error response. In the situation where a server error is causing a problem, you are likely to receive a 5xx response code from the server with little or no meaningful body (text/plain). Where an application error has occured you should also receive a 5xx (or a 4xx) code from the server – however having declared you are able to handle a more specific media type (application/vnd.error+xml for example), you are able to present more information to the user than you would otherwise be able to.
Take the situation where you are consuming an API which serves up application/hal+xml and text/plain (hal for the resource representation, and a plain text for an error). The server is free to be able to add support for representing errors in application/vnd.error+xml without affecting any existing client – as long as the server continues to serve text/plain unless the new media type is deemed as acceptable to the client. Once the client is updated to add support for the new media type, it can take advantage of the additional information that can be provided.
A RESTful API will contain explicit directives that declare if and for how long the response body can be cached for. This information is contained across Cache-Control / Vary headers or Expires header. If the response to your request comes back from the server and declared itself as being able to be cached (only Cache-Control: no-store is excluded from user-agent caches) then you should store it locally and serve up the cached response as long as it’s valid.
There are of course already libraries you can use in your projects that will handle cacheing for you. If you usually use PHP for this stuff (I do), then I highly recommend you take a look at Guzzle to handle this for you.
Yeah i’m going to talk about it again. Hypertext as the engine of application state. Golden rule #1, never construct links in code (unless you’re following a URI Template) – follow them from the links given to you in the resource. This means that when these links change – you don’t have to worry about your app breaking. #2, use the defined link relations of the hypermedia type to navigate through the application (ie, HTML’s ‘rel’ attribute on the link tag). That’s about it. Don’t assume anything if it’s not defined by the media type rules and the representation you receive and you can’t go wrong.