RESTFul Web Services is one of the older books on how engineers should design and build a REST API. It was released in 2007, which in Internet years is eons ago. It was one of the books I read while getting up to speed with different facets of RESTful architecture while helping to build a Java JSR-311 JAX-RS implementation. Sometimes I find it interesting to re-read older books to see if the authors were able to correctly predict “the future”, if the ideas “stood the test of time”, and if anyone followed their advice.
Resource-Oriented Architecture (ROA)
The main discussion of the book centers around Leonard Richardson and Sam Ruby’s Resource-Oriented Architecture (ROA), which has 4 concepts:
1. Resources 2. Their names (URIs) 3. Their representations 4. The links between them
I don’t know if it was revolutionary thinking at the time, but it certainly seemed to clarify what Dr. Roy Fielding wrote in his dissertation into a simple 4 item list. It was not a claim that ROA was the only way to build a RESTful service, but the book is a pragmatic way to break down how to build one.
In my experience, most self-proclaimed RESTful APIs usually get the first 3 concepts correct to some degree, but generally outright fail with the fourth concept, “The links between them”. Fielding called out that REST APIs must be hypertext-driven in 2008 yet it still does not seem many APIs follow that design principle. Part of the problem may be that JSON, which has become the default API media type, is not hypertext-driven even though there are some JSON API standards which try to improve the situation. Another solution with link headers seems to come and go in style.
There were 4 properties of ROA which were also declared at the end of Chapter 4:
1. Addressibility 2. Statelessness 3. Connectedness 4. A uniform interface
Most RESTful web services get at least Addressibility and “A uniform interface” right. It is rare to see overloaded RPC-style POST method operations in a “RESTful” API anymore. Most RESTful APIs understand the pragmatic difference between PUT vs. POST. Stateleness is usually achieved with some caveats. Connectedness is perhaps the most difficult of the listed properties to implement.
All things considered, it seems that the authors did outline how a RESTful architecture should be designed and implemented correctly, and most services are trying to achieve all the properties of a RESTful service.
Somewhat Uncommon, Yet Still Interesting Ideas
URIs containing content language and content type
The recommendation to prefer the URI to contain the content type (e.g. end in “.json”) and content language (e.g. end in “.en.html” to represent an English HTML document) versus the Accept and Accept-Language header was interesting. While perhaps not uncommon in some frameworks, other frameworks have totally gone all-in for HTTP headers to determine the resource representation and media type.
After having to explain over the years about how to get JSON vs. XML with an Accept header and how to manually do content negotiation on the server side, the resource content type in the URI is great pragmatic advice which I wish all frameworks would at least support.
It is easy to copy and give a URI to another person to get the same representation in the same media type. Asking someone to launch their non-browser client and specifying a HTTP header is one of the most inconvenient ways to try an API.
POST(a) for appending to a standalone resource
The authors make a distinction between POST append (POST(a)) vs. POST overloaded to distinguish between using POST as part of a uniform interface vs. using POST as a way to introduce RPC methods.
What was more interesting is that many APIs today use collection factory resources that are POSTed to and which then create child resources. However, another way to use HTTP POST is to append to a standalone resource itself vs creating a child resource. While I believe it is uncommon, it is still a valid RESTful usage of POST.
Comma for Ordered, Semi-colon for Unordered
While I have not seen too many commas or semi-colons in URIs lately, the proposed convention is nice to have for un-keyed parameters. Practically though, it seems everyone has adopted named query parameters. Matrix parameters seem like a forgotten URI convention.
Create More Resources
Many RESTful APIs take a simple approach and expose database tables as resources. However, many times the uniform interface is not adequate to describe all the operations on a resource. Instead of overloading POST and becoming an RPC-style service, the general recommended solution is to create more resources.
For instance, instead of creating a transaction RPC operation, you can create a transaction resource to represent all of the changes and then modify its state to be committed to execute the transaction.
While this approach generally works for simple transactions, queued jobs, etc., it may not be suitable in a more complex system.
The Book Wasn’t Always Right
While the overall ROA design discussion still holds up today, there are a couple of ideas that have grown out of favor as time has gone by. ATOM and XML in general are now secondary media types to JSON for APIs. WADL has not gained any traction over the years either.
Things Only Briefly Mentioned
Service versioning schemes, complex transactions, and batch operations are each briefly mentioned, yet are usually hot topics for any mature RESTful API.
Each are difficult areas to design which I hope is more thoroughly discussed in other books…
There’s a Sequel
What prompted me to re-read this book was that I found out there was a sequel called RESTful Web APIs published in late 2013. I wanted to have a quick read to compare how the authors thoughts changed and how they were revised as a significant amount of time passed. Hopefully I’ll be able to write another blog post in the future about the follow-up book.