Diving into REST is a bit like going into MVC: you think you can learn something about how it works by studying and following current implementations. Quickly you find how much the implementations differ from each other and how little they have in common.
This is because the fundamentals are often forgotten by the implementers. They produce something that kind of looks like what it is named after, but also kind of misses the point.
I am wrting a library to help me connect website front ends to SugarCRM – the front end often being called a “user portal”. The API provided by SugarCRM is declared to be a REST API. Unfortunately it kind of isn’t; instead it just exposes all the existing SOAP methods to a single entry point URL using POST parameters for everything.
All returned data and statuses are supplied in a JSON stcuture – no proper use of HTTP codes. Only POST is used, so the action has to be described in the POST data rather than the HTTP request (e.g. PUT, GET).
Versioning is done via the URL. There is a /service/v2/rest.php entry point, a /service/v3/rest.php entry point and a /service/v4/rest.php entry point, all with different methods implemented in different ways. It gets worse. The data structures that are accepted and returned depend on the underlying version of SugarCRM and not the version of the API you use, so the V3 API will change over time as.
Anyway, that is where not to learn about REST. So where do we go to learn how to do things properly?
Nobody Understands REST or HTTP
Steve Klabnik summarises the basic REST concepts very well:
The examples he gives to show how the resource (the noun) is separated from the action (the verb) by identifying the former in the URL and keeping the action in the HTTP headers. That is kind of obvious for people who are familiar with REST, but is seldom described so clearly, and is a rule so often broken in implementations.
The RESTful Cookbook
The RESTful Cookbook digs into some great techniques:
One I am particularly interested in, is asynchronous operations. These happen when you through a resource at the server for processing, and just get a temporary ticket back to say, “yes, it is in the queue for processing”. The resource location points to its position in the queue. Once it is processed – or discarded – then it gets a more permanent URI.
My interest in this is in processing long-running data imports and exports. These processes would be pushed to a queue such as beanstalkd and processed offline. What it also means is that the application needs a decent framework to track these jobs. Once a job has gone from the queue, the fact that it was there still needs to be recorded for a while. For example, when the browser says, “how is my import at /import-queue/1234 getting on?”, there needs to be way to tell it that the resource has now moved to /imports/5678 using a 303 HTTP code.
I am still looking for a decent PHP wrapper library for beanstalkd that will handle all these things for a framework – keeping track of where jobs are, logging the results, firing off triggers to other processes when jobs are complete and providing a general exchange for queued jobs so that they are directed to the appropriate methods within the framework according to what data they contain, and therefore how it needs to be processed. More of this in another post.
The Resty library available as a Composer package from Packagist is handy for many “REST” interfaces. It does not follow any specific frameworks, but provides a low-level wrapper to HTTP services that can be easily customised.
Resty is especially good for APIs such as that provided by SugarCRM because it does not make any assumptions on how it works. You just put the URL, parameters, options, headers etc. together and call up the API and get the result.
It is lightweight, and does not have a tonne of dependencies to manage, so slips into a product very easily.
I’ll add further resources here when I can.