REST APIs are becoming more and more popular: they allow horizontal scalability, they are flexible to change and easy to use without the need of detailed documentation.
However, some APIs claim to be RESTful when they are not. This is mainly for two reasons:
– We don’t always have a clear idea of what RESTful means, we just associate it to the HTTP protocol standards.
– Building a pure RESTful API can be really challenging.
What are the features of a REST API? What are the benefits of developing a pure REST API?
Not only it needs to use the standard HTTP methods, but it needs to use them with their standard meaning.
By definition, an operation is idempotent if it always have the same effect whether applied once or multiple times. The following HTTP methods should always be idempotent:
– GET: when retrieving existing information without altering the status of our system.
– PUT: when updating/adding to an existing resource. Note that by applying this operation more than once, we shouldn’t create any side effect.
– DELETE: when deleting a resource. If we try to remove a resource that doesn’t exist or that it has already been deleted, this shouldn’t cause a different behaviour of the API.
– HEAD: same as GET, but with an empty body. This is usually used to retrieve metadata about large data without actually retrieving it.
– OPTIONS: when retrieving information about what the methods are allowed by the URI.
There is only one HTTP method that is non-idempotent:
– POST: when creating a new resource. This is not idempotent as we shouldn’t be able to create a resource that already exists.
Also, our return codes should respect the HTTP standards. The most used ones:
– 200 means “OK”
– 204 means: “OK” with empty body
– 400 means “Bad Request”
– 404 means “Resource not found”
– 500 means “Internal Error”
For a list of all HTTP code status see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.
Adopting HTTP standards allows us to safely depend on and use the API: we will know that when using an idempotent method, we can safely repeat the operation if needed. On the other side, when POSTing, we are aware that this can cause side effects that we need to take care of.
Each resource should be uniquely identified by a URI: every time a resource is created it needs to have an address that identifies it.
Addressability is also about readability and predictability: not only the URI should be informative on what the resource is, but it should also be easy to remember and consistent with the other URIs we have created so far.
There are a lot of different opinions on how to build efficient URIs (e.g.: http://www.restapitutorial.com/lessons/restfulresourcenaming.html), chose one convention and stick to it! This will make your API a lot easier to use and our clients a lot happier!
Resources need to be linked together…literally!
While a SOAP API uses a WSDL to define the communication between client and service, a REST API doesn’t have such a technical precise definition of what it can do: as a client we should learn how to use the API by using it, we shouldn’t necessarily rely on any official documentation. One way of achieving this is by using hypermedia to link resources together. For example, if we return the information about a customer we could provide the URI to retrieve all his accounts. We could also prove URIs that provide and explain specific values (e.g.: enums, query params, etc) accepted/returned by that specific operation.
Statuses should never be maintained by the system: they should either be provided by the client or stored in a database. Although this seems to be a small detail, this allows our service horizontally: when our service in under lots of pressure due to high demand, we just need to run a new node of the service to increase our computational power. This operation is completely seamless to our clients because API calls are not influenced by previous calls (i.e.: they are stateless). Another advantage is that stateless calls are also independent between each other: it will allow us to parallelize some calls without worrying too much about side effects.