What is REST?
Is one of the questions I (and I am sure others do as well) often ask when interviewing senior developers and architects. The most common answer is
REST is how we build API's or
Json because that's what we get back from our API calls or
REST is web architecture or pattern. So, let's talk about REST.
Straight from the horse's mouth
Rest was described by Roy Fielding in his Phd dissertation as:
Representational State Transfer is intended to evoke an image of how a well-designed(1) web application(2) behaves: it is a network of Web resources (a virtual state-machine) where the user progresses through the application by selecting links, such as /user/tom, and operations such as GET or DELETE (state transitions), resulting in the next resource (representing the next state of the application) being transferred to the user for their use
Mr. Fielding's definition is interesting; it implies that we have a Web Application(2), then describes how a Well-designed(1) application should behave. This also implies that REST is not a standard, it's an architectural style to which standards are applied when implemented.
It is important to remember that REST is completely protocol agnostic. JSON is not part of REST, and even though we always use HTTP to build RESTFUL API's, HTTP is not part of REST either.
As an architectural style, REST is described by a set of six constraints (one is optional. These constraints can also be seen as design decisions with positive and negative implications, but in all cases the benefits outweigh the disadvantages.
- Client-Server: A client/consumer shouldn't know or even be concerned over how the data is stored or what the server does to retrieve the requested data. The same also applies to the server, it shouldn't be concerned over how the client or the consumer represents the resource.
- Statelessness: The necessary state to handle every request must be contained within the request itself. A consumer requests a resource and that request should contain all information required to service the request. Statelessness is one of the constraints that ensures that RESTful APIs can scale easily.
- Cacheable: Each response message must state explicitly if it can be cached or not. This constraint allows us to eliminate some of the client server interaction and prevents the client from using out of date data.
- Layered System: A REST based solution can be comprised of multiple architectures layers (just like common applications). These layers can be modified and removed as long as they do not have a direct access to next one in the architectural hierarchy. Consumers of an API must be restricted to a single layer without any knowledge of the layer location/position in the architecture.
- Uniform Interface: This constraints states that APIs and consumers share one single, technical interface: URI, Method and Media Type. This constraint is divided into four sub-constraints:
- Identification of Resources:
- URIs are used to identify each resource identified in the request.
- A resource is conceptually separate from its representation (requested resources are not mapped to the requested entity in the database). APIs can service requests for the same resource using different media types (application/json, application/xml or custom media types).
- Manipulation of Resources Through Representation:
- When a consumer holds a representation of a resource including any possible metadata, it has enough information to modify or delete the resource on the server, provided it has sufficient permission to do so. For example, if an API supports deleting a resource, the response could include the URI to delete the resource.
- Self-Descriptive Message: Each message must include enough information to describe how it should be processed. If a message's request body contains JSON representation of a specific resource, the message must specify that by using an application/json media type in its headers to allow the API's correct parser to serialize the message body into the corresponding entity/class.
- Hypermedia as the Engine of Application State (HATEOAS): This is the main constraint that a lot of RESTful APIs fail to implement. It simply means that a hypertext should be used to navigate your way through an API. For example:
GET /Account/1290345 HTTP/1.1
HTTP/1.1 200 OK
<link rel="Deposit" href="/Account/1290345/Deposit" />
<link rel="Withdraw" href="/Account/1290345/Withdraw" />
<link rel="Transfer" href="/Account/1290345/Transfer" />
<link rel="Close" href="/Account/1290345/Close" />
The above snippet contains an XML response for an HTTP GET, but it also contains a hyperlink to deposit, withdraw, transfer, and close the account. The consumer has all the information it requires to perform any operation on this account representation.
Ryan Tomayko's post How I explained REST to my wife
That's it for the day. Next time, we will dive more into each of these constraints.