This is an extract from my book “API on Rails”.
REST is an acronym standing for REpresentational State Transfer and a way of architecturing web services. It was defined in 2000 by Roy Fielding, one of the authors of the HTTP specification and ex-chairman of the Apache Software Foundation, in his dissertation entitled Architectural Styles and the Design of Network-based Software Architectures.
Later on, Fielding described REST as the result of a long discussion of the HTTP specification:
Throughout the HTTP standardization process, I was called on to defend the design choices of the Web. That is an extremely difficult thing to do within a process that accepts proposals from anyone on a topic that was rapidly becoming the center of an entire industry. I had comments from well over 500 developers, many of whom were distinguished engineers with decades of experience, and I had to explain everything from the most abstract notions of Web interaction to the finest details of HTTP syntax. That process honed my model down to a core set of principles, properties, and constraints that are now called REST.
During the last decade, REST has quickly become the de-facto standard for the implementation of public-facing web APIs, even though a few alternatives exist. A comparison of REST with the two most popular web service architectures, SOAP and RPC, can be found in the last paragraph and will help clarify why REST has become so popular.
These are the key concepts of a RESTful web service. We’ll be expanding on what constraints REST imposes on each one of them in the next paragraph.
Resource
: A resource is a concept in your application (user, blog post etc.) which can be uniquely identified and operated on. Nouns are preferred over verbs for resource names. When REST is implemented over HTTP, resources are identified through a URI (e.g. /users/1
).
Representation
: A representation is a document which contains the state of a resource. Representations might be created both by the server (when it sends a resource to the client) and the client (e.g. when describing what updates to apply to a resource). For instance, the same user could be served in JSON and XML.
Server
: A server stores information about the resources accessible through the web service and allows clients to operate on them. Note that a logical server might consist of several physical servers operating transparently under the same identity. In fact, this is usually the case in large web services, for redundancy and performance. Servers do not expose a UI (User Interface).
Client
: A client calls a server to operate a resources. Clients do not store any authoritative information about the resources, but might store context about them and/or how the web service i being used (e.g. authentication information) to improve the UX. Clients also provide a UI which can be graphical, textual or both.
Request/response
: RESTful web services operate in request/response cycles. The client sends a request to the server, which handles it and returns a response.
In order to implement REST, a web service has to implement the following architectural constraints.
If any of the above constraints is not respected, a web service cannot be considered strictly RESTful. The only exception is the Code-On-Demand constraint, which is optional.
RESTfulness is a binary feature: your web service is either RESTful, when it implements all the requirements, or non-RESTful. However, not all non-RESTful services are created alike: some of them are very non-RESTful, some are a little bit non-RESTful, some are five minutes of work away from RESTfulness.
Leonard Richardson devised a scale comprised of four levels of (non-)RESTfulness, where each level builds upon and expands the previous one. It is called the Richardson Maturity Model and Martin Fowler wrote a blog post that summarizes it pretty effectively, but we’re also going to give our description of it:
Again, these four levels are all preconditions of a RESTful web service: they must all be implemented (and more) for a web service to be called RESTful.
Here’s another acronym for you: HATEOAS. It stands for Hypermedia As The Engine Of Application State and it’s the concept behind the third level of the Richardson Maturity Model.
The principle is that a client should be able to enter the web service through a fixed entrypoint and perform all subsequent interactions through hypermedia provided by the responses. This distinguishes REST from other architectures where the client constructs its requests from the documentation (either human or machine-readable).
Let’s see an example response from an API implementing HATEOAS (note that HTTP headers are preferred and used in this book, but links can also be included in the body):
GET /posts/1
Link: </posts/1>; rel="self",
</posts/1/comments>; rel="comments"
{
"id": 1,
"title": "My blog post"
}
As you can see, the response headers contain a Link
header that exposes two links:
Note that the headers do not tell the client anything about what to do with the related resources: they only tell them where they can be found. HATEOAS does not have anything to do with machines magically understanding how to use our API, as it is commonly misunderstood; it simply guarantees that clients can perform a flow of related operations without ever “leaving” the web service.
HATEOAS is what makes REST so resilient to change and so similar to how the web works: when you visit a website, you only enter the homepage’s URL. From that point, all interactions happen by clicking on a link or button (i.e. they are driven by the hypertext). Unfortunately, HATEOAS is also the least implemented of the REST architectural constraints. As a result, a great part of the “RESTful” APIs are not really RESTful (they usually belong to level 2 of the Richardson Maturity Model): if websites worked the same way, you’d have to build all the URLs by hand, referring to the website’s documentation.
The HATEOAS situation is so bad that Roy Fielding wrote a blog post about it. Please, don’t be the guy who makes Roy mad.
This section briefly compares the REST web service architecture with the most popular alternatives, presenting the advantages and drawbacks of each approach.
It is worth noting that this comparison is not formally correct, since REST is an architectural style, while both SOAP and (XML-)RPC are information exchange protocols. For the sake of simplicity, we will be using the protocol name to also reference an architectural style that uses the protocol.
SOAP (Simple Object Access Protocol) is an information exchange protocol designed in 1998 at Microsoft. It reached the W3C recommendation status in 2003, thus becoming a standard.
SOAP uses XML Information Set (which is not necessarily expressed in XML) to deliver structured information. A SOAP message is made of three (sometimes four) parts:
Envelope
: The envelope wraps the XML document, identifying it as a SOAP message.
Header
: The header contains application-specific information about the SOAP message.
Body
: The body contains the call and the response of the SOAP message.
Fault
: This section contains any errors occurred while processing the call.
Here’s an example SOAP message (taken from Wikipedia):
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:m="http://www.example.org/stock/Surya">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetStockPrice>
<m:StockName>IBM</m:StockName>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>
The SOAP protocol presents many disadvantages when compared with REST:
The rigidness of SOAP is, at the same time, an advantage: since both the server and the client must adhere to a pre-defined contract, any violations of the contract are easy to spot automatically.
RPC (Remote Procedure Call) is a kind of request-response protocol that dates back to the beginning of time. At its simplest, a computer sends a request to another computer to perform a specific procedure with specific parameters. The receiver parses the request, performs it and returns a response to the client. There is a bit more to it, but this is explanation will work for our comparison.
RPC can be encoded in many different languages, the most common being XML (JSON is supported too). RPC over XML is called XML-RPC.
Here’s an example XML-RPC request:
<?xml version="1.0"?>
<methodCall>
<methodName>users.getUserName</methodName>
<params>
<param>
<value><int>1</int></value>
</param>
</params>
</methodCall>
And here’s what the corresponding response looks like:
<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><string>John Doe</string></value>
</param>
</params>
</methodResponse>
As you can see from the example, the main difference between REST and RPC is that, while REST focuses on information, RPC focuses on function.
RPC has some advantages over REST:
On the other hand, it also has disadvantages: as with RPC, no standard verbs are used, so there is no guarantee of safety, idempotence or cacheability.