Many Web API designers claim their are RESTful, but their APIs have little in common with REST. What can be done to make a web service API truly RESTful?
According to Roy Fielding’ doctoral thesis, Architectural Styles and the Design of Network-based Software Architectures, REST is the architectural style that the WWW is built upon, based on a number of principles and constraints that are meant to enforce those principles.
Without attempting to be exhaustive, we will enumerate some of the principles that are significant for our discussion, followed by short descriptions:
- Resource Identification. Every resource on the web is uniquely identified by an ID, which is a URI.
- Linking. A client navigates from resource to resource via hypermedia.
- Multiple resource representations. A client does not deal with the resource itself, but with a representation of it. There can be multiple representations of a resource.
Other principles are Server-client Stateless Communication, Using Standardized Methods, Self-descriptive Messages, etc.
Since Fielding’s paper, web APIs have been proliferating all over the Internet, and many API creators qualify their offspring as RESTful, i.e. adhering to REST principles.
While these do their job well, and many are successfully replacing the older WS-* solutions, the question is: Are they truly RESTful or is the term misused, transforming it into a buzz word?
Any “RESTful” API manual suggests defining resources (entities), giving them names (nouns), using plural, creating URIs that suggest the relationships between entities, avoiding deep linking, etc.. A typical request/response on such an API looks like this:
Request
GET /books/10
Response
200 OK
{
"book":{
"id":"10",
"title": "some_title",
"author": "some_author"
}
}
While such APIs have borrowed some of the REST principles, such as identifying each resource by an ID, accessing resources via hyperlinks, providing multiple representations for resources (JSON, XML) – they do not abide to all REST principles, applying the so called “pragmatic REST”, resulting in multiple interpretations of REST. Fielding expressed his frustration with “RESTful” API implementations years ago, informing API designers that several rules need to be followed for an API to be called RESTful, which we quote in brief:
- A REST API should not be dependent on any single communication protocol
- A REST API should not contain any changes to the communication protocols
- A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state …
- A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server).
- A REST API should never have “typed” resources that are significant to the client.
- A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) …
Regarding the last rule, many web APIs today do not have an initial bookmark that a client accesses followed by a way to provide in each response additional links or templates for creating these links to access the various resources that the respective web service has to offer, but usually there is external documentation for developers to follow when constructing such links. If, according to Fielding, this is not a RESTful way of dealing with hyperlinks, then what is it and how could it be done?
Stefan Tilkov, self proclaimed lead RESTafarian of innoQ, suggested during his GOTO session “REST: I don't Think it Means What You Think it Does”, the use of a service document (video at 35m26s), which would be the homepage of a web service. The client would ask for this homepage, which is the service bookmark, and would receive a response containing the available resources, the operations that can be executed against them, and the relative links to be used to access them, as shown in the following example of an Order Management service:
<?xml version="1.0" encoding="UTF-8"?>
<serviceDescription xml:base="http://om.example.com">
<link rel="all" href="/orders/" />
<link rel="received" href="/orders/received/" />
<link rel="accepted" href="/orders/accepted/" />
<link rel="rejected" href="/orders/rejected/" />
<link rel="cancelled" href="/orders/cancelled/" />
<link rel="fulfilled" href="http://om.archive.com/orders/" />
<link rel="cancellations" href="/cancellations/" />
<link rel="reports" href="/reports/" />
</serviceDescription>
{ "serviceDescription" : {
"base": ",
"links": [
{ "rel": "all", "href": "/orders/" },
{ "rel": "received", "href": "/orders/received/" },
{ "rel": "accepted", "href": "/orders/accepted/" },
{ "rel": "rejected", "href": "/orders/rejected/" },
{ "rel": "cancelled", "href": "/orders/cancelled/" },
{ "rel": "fulfilled", "href": "/orders/fulfilled/" },
{ "rel": "cancellations", "href": "/cancellations/" },
{ "rel": "reports", "href": "/reports/" }
]
}
}
While this approach may seem to complicate things by introducing a level of indirection in constructing the hyperlinks, the benefit it brings is decoupling between the client and server. The client no longer has to hardcode the links or build them based on some external guideline, but it gets them from the server. The server can change the links anytime it wants, and can introduce or remove resource operations without having to fear that it might break some clients. Actually, according to Tilkov, some enterprises do exactly that: intentionally messing up with the links to see what clients break, to see where REST principles are not respected.
Also, responses from a server should include state transition links. When the client operates on a resource, the response can contain links to further operations that correspond to possible transition states.
For today’s web APIs, the URLs have become the APIs, transforming REST into a number of URI patterns plus HTTP methods, such as GET, PUT, POST, DELETE
. During the same session, Tilkov asked the audience if the following URIs are RESTful (video at 17m16s):
http://example.com/customers/format?drive=c
http://example.com/customers/getDetails?id=13
http://example.com/customers/delete?id=13
http://example.com/customers/13
http://example.com/customers/13/edit
The replies varied: depending on the URI, some considered them as RESTful while others as not, highlighting the actual confusion that has been created around REST. Tilkov’s take on this was that it does not matter what’s in a URI because from REST’s perspective a URI is just a string of characters, no matter what is inside it. There are no constraints on URIs to make them RESTful. What actually matters is the context in which the URI is used.
Another issue raised by Tilkov was versioning the APIs within the URI, as many leading web API creators do, as shown by the following samples taken from their respective websites:
Swagger word API example: http://api.wordnik.com:80/v4/word.json/home
Apigee Edge API example: https://api.enterprise.apigee.com/v1/organizations
SauceLabs example: https://saucelabs.com/rest/v1/:username/activity
Tilkov explained that this happens because “the URI expresses the API”, wondering “what happens when one changes the API?” He considers that the URI could include a version number if it refers to a certain version of data or a document, but one should not tie an API to URIs pointing to resources because this introduces a coupling between the client and the server.
He provided a number of other recommendations on making APIs RESTful:
- Use advanced hypermedia controls, such as forms, even for machine-to-machine communication
- Use advanced hypermedia controls, such as forms, even for machine-to-machine communication
- Use different media types for different type of resources
- Create new resources if the need arises
- Reserve space for links
It’s obvious that today many web APIs are not RESTful. Nothing stops the respective companies to build such APIs, and they have been quite successful at doing so. What we do not understand is why they insist on calling them RESTful? They could coin another term. Web API could be enough.
It also remains to be seen who will win in the end, if there will be a winner or rather a peaceful coexistence between the two: REST or wannabe RESTful web APIs? In a discussion with InfoQ, Tilkov expressed his confidence that REST “has more than just theoretical advantages, and in the past couple of decades, the web approach always won in the end.” In the meantime, the not-really-RESTful Web APIs have taken over the web. In the ProgrammableWeb index there are currently 12,199 APIs and counting, with over 6,000 being categorized as “RESTful”.
About the Author
Abel Avram has been involved in many InfoQ editorial activities since 2008, enjoying writing news reports on Mobile, HTML, .NET, Cloud Computing, EA and other topics. If you are interested in submitting a news story or educational articles please contact him at abel [at] infoq.com.