In my previous post, I detail how REST allows us to utilise the HTTP’s native caching functionality without the need for additional technologies or knowledge. However, this whole ‘using what we know about HTTP already’ philosophy goes much deeper than that.
Consider one of the biggest problems with API design and maintenance: getting your clients to use the API correctly, especially when it’s changing or is constant development. This might be easy if you are integrating with one team that sits next to you (and even then misunderstandings can arise), but what if you have multiple clients across the organisation, or if you API is public? Read on if you want to see how REST can help….
When clients are using a proper REST based API, they are essentially limited to using a handful of ‘methods’ based on HTTP’s nouns, usually just PUT, GET, POST and DELETE. These methods have been around for nearly three decades, and their basic semantics are clearly defined. Therefore any developer working with HTTP can be assumed to know what they do and how they react.
- GET should be idempotent, and should never update data on the server. You should be able to call it again and again without it having any side-affects.
- POST should add a new item of data to the system (returning and identifier, while PUT should take that identifier and update the item with modified data).
- DELETE deletes the item.
Compare this to technologies such as XML-RPC, or ‘RPC over HTTP‘, or SOAP, where you can have any number of methods, all with their own meanings, parameters, error codes and semantics. In these cases, both Service and Client need to share exactly the same understanding of what all this means; to use the ubiquitous coffee shop example, what method would I need to call to check the status of a coffee order, and if I keep calling that method will anything change on the server side (maybe the barista will get a move on!) ?
In theory, this is easy to resolve using good upfront requirements and diligent documentation. However we all know that this is not how it works in real life; assumptions are made, requirements are ill-thought-out and need to be changed mid-project, and no-one updates the documentation or even bothers to read it.
And don’t get me started with Agile, where iterative development is the leading principle!
But with REST, the core semantics of the API are always stable and understood. A REST GET call to retrieve a CoffeeOrder object will always be idempotent, a new CoffeeOrder object can be created using POST e.t.c. A 201 response code means the order was created, a 403 means that the client didn’t have the authorization to create an order. All this can be assumed from the get go before the project has even started.
However, this means that a lot of the complexity of your application and how it is used is offloaded into the REST objects themselves, and the semantics behind those objects. The API for creating a CoffeeOrder may be simplified and stable due to our usage of REST, but what a CoffeeOrder represents, it’s life-cycle and it’s restrictions still need to be defined nad understood by all parties.
For example, what happens if an order is cancelled? Do we delete the CoffeeOrder item? Update it with a ‘cancelled’ value in it’s status field? How do we denote that a CoffeeOrder has been fulfilled? Do we create a Receipt object? All this needs to be defined, understood and shared, and is subject to a lot of the same problems as the other technologies mentioned (e.g changes, assumptions, misunderstandings).
Therefore it is wrong to assume that REST is some magic bullet that will solve all your API related woes; it will, however, greatly simplify and stabilise the topography of your API and how it is called, and give your team and the client’s an immediate shared framework of common semantics within which to work.