For many REST is a vastly misunderstood term. The experts in the REST domain know this all too well. To the point they are thinking of renaming it to separate themselves because the confusion is out of control and impossible to re-align with the true definition.
Having an HTTP server accept GET requests or POST and responding with XML, JSON or some other data format is not automatically RESTful. This statement will seem very odd to many reading this.
Unfortunately many of the HTTP-enabled API’s out there such as Twitter, who promote themselves as REST, have created confusion on what REST really is.
The definition of REST lost its way when popular services emerged calling themselves REST which were not. An API like Twitter is ignoring the values of the web and the browser by using HTTP as a transport for RPC (Remote Procedure Call). SOAP services also use HTTP in this way. Instead of doing RPC, HTTP should be used to transfer application state which is what REST is designed for.
It’s not bad for a service to not be RESTful if the problem needing a solution calls for it. Each situation is different and REST has it own set of advantages and disadvantages to consider. The problem is the term REST is being used where it does not belong.
Roy Fielding, one of the principal authors of the HTTP 1.0 and 1.1 specifications introduced REST in 2000 in his doctoral dissertation.
Conforming to the constraints for REST from Roy’s dissertation is referred to as being RESTful. As pointed out earlier these terms are used improperly in cases where the constraints are violated. Simply having a HTTP service that responds with JSON or XML does not make a RESTful service.
Separation of concerns is the purpose of the client-server constraint which is intended to separate user interface concerns from data storage concerns. With the popularity of HTTP-enabled API’s being an integration point for online services the separation of the client and server was already chosen since the client is typically a 3rd party.
The client-server interaction must be stateless in nature. Each request from the client to the server must contain all of the data that is necessary to handle the request. Tackling concurrency and scalability becomes drastically easier when you don’t have to transition state between servers and handle scenarios when state has been mutated in multiple locations. Be careful not to confuse state and resources (data).
As Roy mentions in his dissertation making a choice to adopt an architecture style always has trade-offs. One disadvantage of being stateless is the repetition of data sent in a series of requests.
This constraint in my opinion is one of the first ones violated in self proclaimed REST services. Having the server retain state also has its advantages which for one service may make total sense.
The data within a response to a request must be implicitly or explicitly labeled as cacheable or non-cacheable. The advantage of this constraint reduces partially or completely client to server interactions for a request or series of requests. Gains come in many facets such as user perceived performance and reliability (the service isn’t always required). Data reliability is a trade-off however.
Because of the stateless constraint, understanding when a cache is invalid is easier to identify because you don’t have any cases where server-side state has been mutated on one server but not others and consistency is easily achieved.
Layered system constraint
The layered constraint was added to address improving internet sized scalability requirements. Each layer cannot see beyond the immediate layer with which it is communicating with. This places boundaries on the overall complexity of the system.
Like most solutions for scalability there are usually trade-offs. Latency is increased with the introduction of layers but the cache-constraint above can certainly help reduce the amount of requests over the network.
I would imagine that many would still consider your service RESTful if you bent the rules on this constraint and solved scalability differently. From the outside your clients could interpret your service as being completely RESTful even if you did this differently.
One has to wonder what other constraints you broke if your layers cross all sorts of boundaries. I imagine violating the stateless constraint would cause all kinds of odd topologies as you start to wrestle with the concurrency challenges that introduces.
Pandoras box opened have you? State you’ve allowed Hmm?
The code-on-demand constraint allows clients to be extendable by downloading and executing code. Similarly to java script in a web browser this allows you to add functionality without re-deploying client software.
The code-on-demand constraint is optional.
Information is transferred in a standardized form which is certainly a trade-off. You gain in a common standard for information but you lose in efficiency by the inability to handle a specific applications needs.
REST has 4 interface constraints. I’m not going to go through all of them but I’ll give a quick summary:
Identification of resources
Each resource has a URI and is access through a defined set of HTTP methods (GET, PUT, POST, DELETE)
Manipulation of resources through representations
Each resource can have one or more representations. Such as application/xml, application/json, text/html, etc. Clients and servers negotiate to select representation.
Requests and responses contain not only data but additional headers describing how the content should be handled. Such as if it should be cached, authentication requirements, etc.
Hypermedia as the engine for application state
I’m going to focus on the last interface constraint Hypermedia as the engine for application state because I think there is a lot to learn when it comes to hypermedia and why many services are not RESTful by violating this constraint.
A REST API must be hypertext driven
Hypermedia as the engine for application state is the 4th Uniform interface constraint.
Roy himself has gotten frustrated by the misuse of the term REST and blogged about it with some great info on why certain services are not RESTful.
After talking with Darrel Miller and reading Roy’s post the key awareness I came out of it was that the use of hypermedia, particularly hypertext and linking are very important.
A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server). Servers must have the freedom to control their own namespace. Instead, allow servers to instruct clients on how to construct appropriate URIs, such as is done in HTML forms and URI templates, by defining those instructions within media types and link relations. [Failure here implies that clients are assuming a resource structure due to out-of band information, such as a domain-specific standard, which is the data-oriented equivalent to RPC's functional coupling].
An example of hypertext aware clients are web browsers.
In my observation many services which claim to be REST but are not exclude hypertext and requires deep knowledge of the services API to understand how to navigate the application.
Let’s look into a Twitter response and discover what is missing and what hypertext enables which is required for REST.
Not RESTful (Twitter)
|1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17||
The Twitter API also has API for looking at a users profile. Notice how the <user> element has no hyperlink to direct the client to the location of where the user resource is located. This means unlike a browser, a Twitter client needs to understand deep knowledge of the Twitter API to navigate to the user resource. If the Twitter API was RESTful within the response the <user> element would have a hyperlink which the client could automatically understand. The benefits of this are many and one of the most obvious ones is if Twitter changes its URI for user profiles the client would require no changes because like a browser the server response includes hyperlinks and the client understands them.
RESTful (Twitter modified)
|1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17||
Notice the href in the above XML markup. With the inclusion of hypertext, a RESTful client can navigate this all by it’s own just like a browser does when it makes links clickable by the user.
It is important to point out that in the world of REST a link may have uses outside of user navigation. The client could use links to navigate the data. A link could also be used for previous or next records for example.
Ever read a multi-page article on a website that has a next page link? The browser just knows how to handle that. RESTful clients often behave the same way.
Let’s take an Atom reader for example. The Atom format supports hypertext and you can easily see the benefits over the Twitter response.
|1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27||
Lines 9 and 10 show how Atom allows the client to understand it’s current location as well as where to navigate for the next collection of results. Atom clients can be far more dynamic than Twitter clients because of the use of hypermedia.
Line 25 you can see the inclusion of an edit link. By using the rel attribute Atom clients can automatically understand where to navigate for editing. The use of hypermedia specifically hypertext enables dynamic scenarios non-RESTful clients don’t get with responses that include no hypermedia. For this reason Hypertext is a constraint. Without including hypermedia a service is not RESTful.
When we build RESTful systems the way we build clients also changes. The clients behave very much like a browser and the clients start to benefit in the same ways that a browser does. Hypermedia unlocks many scenarios we don’t typically think of when we are accustom to building RPC-style services.
What should be clear after reading this is that many of the services you’ve used and interacted with which call their API a REST API don’t exhibit many of the benefits that the true definition of REST provides and violate many of the key constraints. To re-iterate this does not mean the service is poorly built or does not solve the problem set it attempts to solve. It simply means they are not RESTful. REST comes with it own set of advantages and disadvantages. I described some but not all of these in this post.
Understanding how clients could benefit from hypermedia and particularly hypertext was the “AHA” moment for me which encouraged me to look into this deeper. There is so much more to grasp and understand on this topic I’ve only begun.
I highly suggest reading Roy’s doctoral dissertation where he defines REST.
After spending all weekend on this post I’m going to get some REST myself. Oh who am I kidding…
- The 99th percentile matters
- Batching and pipelining linearizable operations in replicated logs
- Trick to reduce allocations improves response latency in Haywire
- Improving the protocol parsing performance in Redis
- Mencius and Fast Mencius a high performance replicated state machine for WANs
- Tuning Paxos for high-throughput with batching and pipelining
- Scalable Eventually Consistent Counters
- Create benchmarks and results that have value
- Routing aware master elections
- My new test lab
- Responsible benchmarking
- Understanding hardware still matters in the cloud
- The “network partitions are rare” fallacy
- Messaging and event sourcing
- Further reducing memory allocations and use of string functions in Haywire
- HTTP response caching in Haywire
- Atomic sector writes and misdirected writes
- How memory mapped files, filesystems and cloud storage works
- Hello haywire
- Active Anti-Entropy
- October 2014
- September 2014
- May 2014
- April 2014
- March 2014
- February 2014
- January 2014
- November 2013
- October 2013
- August 2013
- July 2013
- June 2013
- May 2013
- April 2013
- March 2013
- January 2013
- October 2012
- September 2012
- August 2012
- May 2012
- April 2012
- February 2012
- January 2012
- December 2011
- September 2011
- July 2011
- June 2011
- May 2011
- April 2011
- March 2011
- February 2011
- December 2010
- November 2010
- October 2010
- September 2010
- August 2010
- July 2010
- June 2010
- May 2010