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.
A statement such as this can be hard to grapple with. If servers control their own namespace without a fixed resource hierarchy, how do clients, and more importantly client developers, get to learn or discover URIs of resources? After all, for a long time, one of the fundamental assumptions of distributed client server development is that, in order to build, maintain and administer such an application, we need a formal description of the interface to the application a priori. Roy Fielding's statement seems to contradict this assumption.
Discussions about descriptions of RESTful systems is not new. Almost always, such discussions conclude with ideas like the above. See, e.g, the note on Debate: Does REST Need a Description Language? at infoQ last year that summarizes some of the discussions that took place then. The state of affairs is not very different today.
Despite a number of opinions expressed both for and against a formal description language for RESTful applications, description languages like WADL have gained some limited ground. However, since there is not a "standard" language that a machine could interpret, the most common route that server applications take is to document all URIs, HTTP methods supported, and structures of representations (e.g. as XML and JSON) so that client application developers can rely on such documentation to write code.
This approach, however, contradicts some of the fundamental principles of REST, as paraphrased by Roy Fielding above. Even if we ignore this objection, for those attempting to build distributed applications over HTTP RESTfully, the fundamental question remains. How can a server get away without formally defining a contract? Without a contract, how can we make sure that clients and servers are implemented correctly, not only to respective design specifications, but to other business/technical policies in place?
Distributed applications using HTTP as an application protocol, and built RESTfully, do have a contract, but of a different nature and kind. We need to know what to look for and where. Along the same lines, if we were to come up with a description language, it can not be similar to WSDL or WADL. My goal in this article is to answer the following questions.
- Why is not there a standard descriptions language for RESTful applications yet?
- How does a contract for RESTful applications looks like?
- What kind of software do we need to build that can understand and take advantage of such a contract?
- If we decide to come up with a machine-readable description, how might it look like?
Let me begin with an example.
Example
The task is to write a client application that can transfer some amount from one bank account to another account of the same customer in a different bank.
Let me first describe all the interactions between the client and the server, and then look at a possible description of the contract.
Step 0: A user logs into the client. In order to keep this discussion focused, let me ignore all security aspects.
Step 1: The client uses a URI http://bank.org/accounts?findby=7t676323a
to search for two accounts using the customer ID. Here 7t676323a
is the ID of a customer who has several accounts registered with the bank. In response, the server returns IDs of two accounts, viz., AZA12093
and ADK31242
, respective customer IDs and current balances, as below.
200 OK Content-Type: application/xml;charset=UTF-8 <accounts xmlns="urn:org:bank:accounts"> <account> <id>AZA12093</id> <customer-id>7t676323a</customer-id> <balance currency="USD">993.95</balance> </account> <account> <id>ADK31242</id> <customer-id>7t676323a</customer-id> <balance currency="USD">534.62</balance> </account> </accounts>
Let me assume that an XML schema bound to an urn:org:bank:accounts
namespace describes the XML documents used in this example.
Step 2: Since the client knows the IDs of both accounts, if necessary, it can submit GET requests to the following URIs to obtain more information of each account.
http://bank.org/account/AZA12093 http://bank.org/account/ADK31242
For this example, as the client has the information it needs to initiate an account transfer, let me skip these requests.
Step 3: The client then issues an account transfer by submitting a POST request as follows.
POST /transfers Host: bank.org Content-Type: application/xml;charset=UTF-8 <transfer xmlns="urn:org:bank:accounts"> <from>account:AZA12093</from> <to>account:ADK31242</to> <amount currency="USD">100</amount> <note>RESTing</note> </transfer>
The server retrieves routing numbers for the accounts, and submits the transfer to some bank-end system to execute the transfer, and returns the following.
201 Created Content-Type: application/xml;charset=UTF-8 <transfer xmlns="urn:org:bank:accounts"> <from>account:AZA12093</from> <to>account:ADK31242</to> <id>transfer:XTA8763</id> <amount currency="USD">100</amount> <note>RESTing</note> </transfer>
The transfer is not done yet. The transfer is going to happen asynchronously over a couple of business days (not unusual for inter-bank transactions), and the client can use the ID of the transaction to find out its status.
Step 4: A day later, the client submits a GET request to find the status.
GET /check/XTA8763 Host: bank.org 200 OK Content-Type: application/xml;charset=UTF-8 <status xmlns="urn:org:bank:accounts"> <code>01</code> <message xml:lang="en">Pending</message> </status>
Note that, although this implementation uses resources, URIs, representations, and HTTP's uniform interface, it is not RESTful. As we will see in the next section, this example does not take advantage of one of the key constraints of REST, viz., that hypermedia be the engine of application state.
Before attempting to make this RESTful, let me try to write a possible user documentation to accompany this example.
Bank.Org API - URIs
http://bank.org/accounts?findby=someparams
Submit a GET request to this URI to search bank accounts. This will return an
accounts
document. See the XML schema for more details.
http://bank.org/account/{account-id}
Submit a GET request to this URI to get account details. Here
{account-id}
is the ID of the account. This will return anaccount
document. See the XML schema for more details.
http://bank.org/transfers
Submit a POST request to this URI to create an account transfer. In the body of the request, include the
transfer
document. If the request is successful, the server will return atransfer
document. See the XML schema for more details.
http://bank.org/check/{transaction-id}
Submit a GET request to this URI to find the status of the transfer. Here,
transaction-id
is the ID of the account transfer. This will return astatus
XML document. See the XML schema for more details.
This style of documentation is the most common today. It includes all the URIs that the client will ever need to use. It describes HTTP methods that clients can use with each URI. It also includes descriptions of representations, viz., the XML documents in this example.
But There are two problems with this style of documentation. First of all, it does not help any one looking for a formal machine-readable description. Without a machine-readable description, we can not build generic software tools that can test or otherwise enforce the contract. The lack of such generic software tools is of considerable impediment for those that need to deploy such tools for managing and governing their software. You may consider using WADL, or even WSDL 2.0 to provide a machine-readable equivalent.
Secondly, and more importantly, describing the server's interface in this manner, whether machine-readable as WADL or WSDL 2.0, or human readable, violates two of the constraints of REST that require that (a) messages be self-describing, and (b) hypermedia be the engine of application state. How so and why does it matter?
Back to the Constraints
The key constraints of REST are (a) identification of resources, (b) manipulation of resources through representations, (c) self- descriptive messages, and (d) hypermedia as the engine of application state.
Messages in a RESTful application using HTTP are self-describing by virtue of two things, firstly, by the use of the stateless uniform interface, and secondly, by the use of HTTP headers that describe the contents of messages in addition to implementing various protocol aspects of HTTP such as content negotiation, conditional requests for caching and optimistic concurrency and so on.
By looking at the HTTP method used, and the request/response headers, an intermediate entity such as a proxy or cache can decipher which part of the protocol (viz., HTTP) is being used and how. Such self-describing messages ensure that client-server interactions are visible (e.g. to caches), reliable (e.g. detecting and recovering from partial failures) and scalable.
The fourth constraint, viz., that hypermedia be the engine of application state serves two purposes. Firstly, it relieves the protocol (viz., HTTP) from being stateful. Secondly, it allows the server to evolve (e.g. by introducing new URIs) and keeps clients loosely coupled to servers.
When a server is providing a description of representations as in previous section, it is not taking advantage of the self-describing nature of HTTP. In HTTP, clients and servers use "media types", or those Content-Type
headers that we see in requests and responses to describe contents of messages, and not XML schemas. A media type is a like the class of an object, or the schema type of an XML element.
Further, when a server is describing all URIs to its clients, it will not be able to evolve on its own, and its interface becomes brittle. Any changes to URIs will most likely break existing clients. But then, how can you write a client without knowing the URIs that it needs to connect to?
The answer lies in using links with known relations. A link is an indirection that a client can use to discover URIs at runtime. A link has at least two properties - a URI, and a relation. The URI points to a resource, or a representation of a resource, while the relation describes the type or kind of the link. A true RESTful server application conveys URIs to clients by including links with predefined relations in its representations. So, instead of having to learn all URIs a priori, the client can extract URIs from links at runtime. Consequently, the server is free change URIs or even introduce new URIs on the same or some other server that provide a compatible behavior.
Finally, links that a server returns in representations can be contextual, by directing what the client can do subsequently. In other words, links dynamically describe the contract between the client and the server in the form of a workflow at runtime.
To sum up, for a RESTful application, the contract contains three different pieces: the uniform interface, media types of representations, and contextual links to resources.
Sounds like a fairy tale? Let me rewrite the above example to show the contract in action.
Example - Rewritten
Step 0: Same as before.
Step 1: The client uses the same URI http://bank.org/accounts?findby=someparams
to search for the accounts. This time, let the server return a different kind of response.
200 OK Content-Type: application/vnd.bank.org.account+xml;charset=UTF-8 <accounts xmlns="urn:org:bank:accounts"> <account> <id>AZA12093</id> <link href="http://bank.org/account/AZA12093" rel="self"/> <link rel="http://bank.org/rel/transfer edit" type="application/vnd.bank.org.transfer+xml" href="http://bank.org/transfers"/> <link rel="http://bank.org/rel/customer" type="application/vnd.bank.org.customer+xml" href="http://bank.org/customer/7t676323a"/> <balance currency="USD">993.95</balance> </account> <account> <id>ADK31242</id> <link href="http://bank.org/account/ADK31242" rel="self"/> <link rel="http://bank.org/rel/transfer" type="application/vnd.bank.org.customer+xml" href="http://bank.org/transfers"/> <link rel="http://bank.org/rel/customer" type="application/vnd.bank.org.customer+xml" href="http://bank.org/customer/7t676323a"/> <balance currency="USD">534.62</balance> </account> </accounts>
In this response, note the value of the Content-Type
header, and the links containing URIs.
Step 2: If the client wants to find out more about each account, it can extract their URIs from the links of "self
" relation from the above response, and submit GET requests to those URIs.
Step 3: In order to initiate an account transfer, the client extracts the URI from the link with "http://bank.org/rel/transfer
" and "edit
" relations from either of the accounts above, and submits a POST request to it.
POST /transfers Host: bank.org Content-Type: application/vnd.bank.org.transfer+xml;charset=UTF-8 <transfer xmlns="urn:org:bank:accounts"> <from>account:AZA12093</from> <to>account:ADK31242</to> <amount currency="USD">100</amount> <note>RESTing</note> </transfer>
Again, note the value of the Content-Type
header.
After initiating the account transfer, the server returns the following.
201 Created Content-Type: application/vnd.bank.org.transfer+xml;charset=UTF-8 <transfer xmlns="urn:org:bank:accounts"> <link rel="self" href="http://bank.org/transfer/XTA8763"/> <link rel="http://bank.org/rel/transfer/from" type="application/vnd.bank.org.account+xml" href="http://bank.org/account/AZA12093"/> <link rel="http://bank.org/rel/transfer/to" type="application/vnd.bank.org.account+xml" href="http://bank.org/account/ADK31242"/> <link rel="http://bank.org/rel/transfer/status" type="application/vnd.bank.org.status+xml" href="http://bank.org/check/XTA8763"/> <id>transfer:XTA8763</id> <amount currency="USD">100</amount> <note>RESTing</note> </transfer>
Step 4: To find the status of the account transfer, the client can extract the URI from the link of relation "http://bank.org/check/XTA8763
" and submit a GET request to it.
This implementation is RESTful as it uses representations with contextual links to encapsulate the state of interactions, i.e., it takes advantage of the constraint that hypermedia be the engine of application state.
Now, let me take a step back and highlight the information required to implement the new set of interactions. To start with, the client needs to know the URI to search for accounts. It then needs to know the names and semantics of various link relations. It also needs to know the details of each media type. It can figure out the rest of the contract dynamically at run time. We can therefore come up with the following revised documentation.
Bank.Org API
URIs
http://bank.org/accounts?findby=someparams
Submit a GET request to this URI to search bank accounts. You can pass customer ID or customer name or customer's social security number as the value of the
findby
query parameter. This resource supportsapplication/vnd.bank.org.accounts+xml
media type.Link Relations
self
The URI of a link with this relation refers the containing resource, such as account and transfer resources.
http://bank.org/rel/transfer
andedit
The URI of a link with these relations can be used to create a new account transfer resource.
http://bank.org/rel/customer
The URI of a link with this relation can be used to fetch a customer resource.
http://bank.org/rel/transfer/from
The URI of a link with this relation identifies the source account resource for the transfer.
http://bank.org/rel/transfer/to
The URI of a link with this relation identifies the target account resource for the transfer.
http://bank.org/rel/transfer/status
The URI of a link with this relation can be used to fetch the status resource.
Media Types
application/vnd.bank.org.accounts+xml
A representation of this media type contains an
accounts
document declared in the namespaceurn:org:bank:accounts
. See the XML schema for more details.
application/vnd.bank.org.transfer+xml
A representation of this media type contains a
transfer
document declared in the namespaceurn:org:bank:accounts
. See the XML schema for more details.
application/vnd.bank.org.customer+xml
A representation of this media type contains a
customer
document described in the namespaceurn:org:bank:customer
. See the XML schema for more details.
application/vnd.bank.org.status+xml
A representation of this media type contains a
status
document described in the namespaceurn:org:bank:transfer
. See the XML schema for more details.
Description of a Different Kind
The approach to describing applications RESTfully that I presented in the previous section has some odd as well as some interesting characteristics.
For those familiar with WSDL and WADL, the description in the previous section may look unconventional. Instead of descriptions of input and output messages for every operation, we see media types. However, since generic media types such as application/xml
are too generic to help us distinguish representation of an account resource from a representation of a customer resource or a transfer resource, in this example I used custom media types. Each of these media types ends with "+xml
", and as per RFC 3023, XML processors (including XMLHttpRequest) can handle such representations as though it is XML. By looking at such media types, the client knows whether it received a representation of an account resource or a transfer resource. More importantly, it does not have to assume anything about the structure or syntax of the URI it used to fetch that representation.
Moreover, instead of listing all the URIs that the application is using, the documentation included just the one URI that the account transfer client needs to start interacting with. Note that, in a different example, we may need to document more than one URIs. The idea is to pre-publish the smallest number possible. Why is this better? It decouples the client from the actual URIs of resources, and the client does not need to know the rest of the URIs until run-time.
Finally, the documentation above did not include HTTP operations applicable for each URI. Instead, I assumed that the client submits an HTTP OPTIONS request on each URI to discover various operations possible, and then uses HTTP GET to get a representation of a resource, HTTP POST to create a new resource in a collection of resources, HTTP PUT to update an existing resource (or create one if the client can assign a URI for the resource), and HTTP DELETE to delete a resource.
To sum this up, describing the contract RESTfully involves the following:
- Pre-publish a few URIs and document the resources that these URIs correspond to. Keep the length of this list as small as possible. These URIs are the starting points for the application.
- Document all media types. For XML based representations, if required, use an XML schema to document the structure of each representation.
- Document all link relations.
- Let clients use HTTP OPTIONS to discover HTTP operations supported for a given URI at runtime. In some cases, the type of the link relation may be sufficient for the client to determine that the server supports a given operation.
Such a description is neither complete nor fully machine-readable.
It is not complete since it just includes the static aspects of the contract, leaving the server to describe the possible workflow at runtime via links.
For those that are already convinced about the benefits of REST and are actively building RESTful applications using HTTP, lack of a completely machine-readable description may not matter.
But for those that are building distributed applications using RPC-like approaches using SOAP, WSDL, and WS-*, and are considering REST, lack of a completely machine-readable description may appear like a show-stopper. However, the amount of work that can be done using a RESTful machine-readable description, if one exists today, is limited. This is due to the following:
- Dynamic nature of the contract: As I described in the example in the previous section, representations describe the dynamic aspects of the contract by using links in representations. Explaining this contextual contract in some XML-based machine readable description outside representations is redundant.
- Flexibility of media types: Unlike SOAP based applications, RESTful applications are not limited to using XML. They can use other media types that do not have schema languages.
Also note that a completely machine-readable description of a contract for a remote interface is a fallacy. A machine-readable description created by using WSDL or WADL can only describe the structure and syntax, but not semantics. But machine-readable descriptions can sometimes help us reduce the amount of work that we, as programmers, testers and administrators, need to do.
If we leave aside the uniform interface and the dynamic aspects of the contract, we can describe the rest of the contract in a machine-readable manner. Here is an example. Note that my intent in this description is only to help tools and frameworks that want to monitor or test client-server interactions, but certainly not to mimic WSDL or WADL.
<description xmlns:bank="urn:org:bank:accounts"> <types> <!-- Include the schema used for all representations --> <include href="bank-schema.rng"/> </types> <!-- List all media types and the corresponding XML types --> <media-types> <media-type> <name>application/vnd.bank.org.accounts+xml</name> <representation>bank:account</representation> </media-type> <media-type> <name>application/vnd.bank.org.transfer+xml</name> <representation>bank:transfer</representation> </media-type> ... </media-types> <relations> <relation> <documentation>This relation ...</documentation> <name>http://bank.org/rel/transfer</name> </relation> ... </relations> <resources> <resource> <name>accounts</name> <media-type-ref>application/vnd.bank.org.accounts+xml</media-type-ref> <uri> <!-- This is optional --> <base>http://bank.org/accounts</base> <params> <param> <documentation>Use this parameter to ...</documentation> <name>findBy</name> </param> </params> </uri> </resource> <resource> <name>transfer</name> <media-type-ref>application/vnd.bank.org.transfer+xml</media-type-ref> </resource> ... </resources> </description>
This is a machine-readable version of the one I described in the previous section, and is certainly not governed by any standard. This description does not eliminate the need for human-readable description, since we still need that to describe the semantics of the application.
Let me highlight the key sections of this description:
- Schema types: Since I chose to use XML for all representations in this example, I included a reference to the schema used. This section would be meaningless if the chosen representation formats are not describable by a schema.
- Media types, and the corresponding XML documents used.
- List of all link relations.
- Names of resources and their media types. Note that the names are not URIs.
- URIs for those resources that provide starting points for the application.
Is this kind of a description more useful than the human-readable description? In the absence of tools and frameworks that can interpret such a description, the answer may be no.
Is this Practical?
If you are writing the server-side code and the client-side code based on a machine-readable contract such as a WADL document, the coding flow may be as follows:
- Generate resource classes from the description. Each resource classes potentially corresponds to a URI in the description.
- Generate classes that bind to representations. If the representations are XML based, I would be generating classes that map to various XML documents.
- Generate client-side stubs that map to various HTTP operations.
- Start coding.
This model won't work for a RESTful description of the contract, and the steps would be different.
- Read the descriptions of all media types. If the media types are described using an XML schema, grab that schema and generate classes that can parse or generate XML.
- Read the description of all link relations.
- Create resource classes manually.
- Whenever the client receives a representation, in addition to extracting the data from the representation, look for links. If you find a link with a known relation, extract the
href
andtype
(if present) attributes for later use. - On the client side, before sending an HTTP request, first send an HTTP OPTIONS request to check if the operation you want to perform is supported by the server. If so, proceed to enable that operation in your client application.
Most software frameworks that I am aware of can deal with some of the steps above, such as common interfaces or conventions for resource classes, and depending on your programming language of choice, be able to generate classes to create or parse XML. But the rest is left up to the developer. More over, most of these frameworks emphasize server-side development, and leave out client-side development under the assumption that existing HTTP client libraries are sufficient. Consequently, you may need to create custom code to deal with items (4) and (5) above.
How about software tools that want to test or enforce the contract? It is possible to create such software that reads the above machine-readable description to do the following at runtime.
- Check that the media types of representations are predefined.
- Check that the representations match the predefined descriptions of media types.
- Check that all links contained in representations have predefined relations and media types, and that the URIs included follow predefined URI patterns.
I am not aware of any software that can validate these in this manner. However opportunities abound. If you have read this article this far, you know what those opportunities are.
Conclusion
One of my goals for this article is to illustrate the fact that traditional descriptions of contract such as WSDL and WADL are not adequate to describe RESTful applications. As I demonstrated with the account transfer example, only a part of the contract can be described statically, and the rest is dynamic and contextual. The client can follow this dynamic part of the contract at runtime by looking at links. You can attempt to describe the former via some machine readable document for design-time or testing purposes, but letting the server describe the rest at runtime reduces the coupling between clients and servers significantly. Attempting to describe the complete contract statically is equivalent to duplicating all the contextual links outside representations.
In contrast, description languages like WSDL and WADL try to describe the contract in a context-free manner, and client developers are left to user documentation to learn how to compose a client application from various message exchange patterns described in those descriptions. In RESTful applications, servers provide this information at runtime in the form of links.
To conclude, RESTful applications do have a contract. We just need to what to look for and where, and remember that the contract is contextual.
About the Author
Subbu works at Yahoo. See his blog for more about him.
Community comments
Great Article
by Michael Cohen,
Re: Great Article
by Subbu Allamaraju,
Re: I like REST, but I need practical framework on how to start coding
by Michael Cohen,
Re: I like REST, but I need practical framework on how to start coding
by Jean-Jacques Dubray,
Re: I like REST, but I need practical framework on how to start coding
by Zubin Wadia,
Re: I like REST, but I need practical framework on how to start coding
by Sreekanth Manga,
Great Article
by Ramkumar KB,
Re: Great Article
by Subbu Allamaraju,
I don't agree to the usage of HTTP OPTIONS
by Sebastian Kirsch,
Document types are actually part of the uniform interface :)
by Benjamin Carlyle,
Re: Document types are actually part of the uniform interface :)
by Subbu Allamaraju,
Re: Document types are actually part of the uniform interface :)
by Subbu Allamaraju,
link@rel defined by uri template?
by peter keane,
Re: link@rel defined by uri template?
by peter keane,
Great Article, some words on WSDL's behalf...
by William Martinez,
Re: Great Article, some words on WSDL's behalf...
by Subbu Allamaraju,
Hybrid aproach
by Antonio Mota,
Re: Hybrid aproach
by Subbu Allamaraju,
Correction
by Subbu Allamaraju,
Typos?
by Nicholas Gall,
Re: Typos?
by Subbu Allamaraju,
Re: Typos?
by Nicholas Gall,
A couple of observations
by Nicholas Gall,
Re: A couple of observations
by Subbu Allamaraju,
Re: A couple of observations
by Nicholas Gall,
Re: A couple of observations
by Subbu Allamaraju,
Thanks and a couple of questions...
by Mark V,
Re: Thanks and a couple of questions...
by Subbu Allamaraju,
Re: Thanks and a couple of questions...
by Mark V,
Re: Thanks and a couple of questions...
by Mark V,
media types
by Viviane Festjens,
RDF - a resource description language
by Bob Ferris,
Generate Spring REST Documentation
by Robert Morschel,
Re: Generate Spring REST Documentation
by Jennie Vecchio,
Great Article
by Michael Cohen,
Your message is awaiting moderation. Thank you for participating in the discussion.
Subbu,
Nicely written article on REST. Your bank.org examples clearly explain how to improve a RESTful design to exhibit full self-describing contracts.
I agree with you that the lack of a universal contract language could be a show stopper for some developers given that it increases the amount of manual development required to bind to the RESTful interface. Variances in RESTful contracts between vendor APIs also diminishes the number of universal tools that can be created to ease the binding for client software. A lack of a universal contract language for REST also means that there is a burden to write code to construct the contract and distribute it through HTTP OPTIONS on the server side. However, given these limitations, the approach still has its positives based on flexibility and simplicity.
Re: I like REST, but I need practical framework on how to start coding
by Michael Cohen,
Your message is awaiting moderation. Thank you for participating in the discussion.
There are a couple of REST-like frameworks. In Java there the free, open source framework called Restlet [1] that now nicely integrates with GWT. In the .NET world, Microsoft has created an free framework called ASP.NET MVC [2] that embraces the power of HTTP and the URL. However, for Subbu's demonstration with his RESTful self-describing contracts there is currently no framework for it (at least that I'm aware of anyway). You'll have to role your own. Without a universal way of describing RESTful contracts it hampers the ability to write consistent frameworks that work on various platforms. That being said, I believe that Subbu has laid down a great foundation that others can build upon and hopefully evolve towards a formal base that everyone can work off of.
[1] www.restlet.org/
[2] www.asp.net/mvc/
Re: I like REST, but I need practical framework on how to start coding
by Jean-Jacques Dubray,
Your message is awaiting moderation. Thank you for participating in the discussion.
Michael:
MVC has nothing to do with REST. MVC binds URLs to actions ("{controller}/{action}/{id}"). This is clearly explained in their tutorial: quickstarts.asp.net/previews/mvc/mvc_RoutingInM...
The MVC pattern is not resource oriented by any means. At the end of the day there are several models that needs to be very clear:
- Web Services: one endpoint per service (any number of operations)
- MVC: one endpoint per action
- REST: one endpoint per resource
- Pub/Sub: one endpoint per queue
Each of these approaches allow you to associate business logic to an endpoint (they also have different activation and concurrency models). The resulting factoring of this business logic is quite different in each case.
Great Article
by Ramkumar KB,
Your message is awaiting moderation. Thank you for participating in the discussion.
Subbu,
This is nicely written. It felt analogous to "how can a machine-client browse"!
Is there a typo in the rewritten example under Media Types for Status? Shouldn't it be: application/vnd.bank.org.status+xml
I don't agree to the usage of HTTP OPTIONS
by Sebastian Kirsch,
Your message is awaiting moderation. Thank you for participating in the discussion.
This article is one of the few that clearly articulate what is meant with "Hypermedia as the engine of application state" - I really appreciate this.
However, I don't agree with the usage of HTTP options. Except for some "automated RESTful crawler", I don't see why any client application should do this. Except for a PUT intending to create a resource, which could be replaced by POST, you cannot interchange the verbs anyway. And even that replacement is somewhat fishy, as I assume that in most cases, the intended URL has at least *some* business value.
In that manner, changing the allowed verbs will definitively break the client code.
link@rel defined by uri template?
by peter keane,
Your message is awaiting moderation. Thank you for participating in the discussion.
Wondering how you feel about link@rel described by a uri template rather than a uri. The reason is that in my system, you can create new entity sub-types runtime, then assert a parent-child relationship between them (also runtime).
It is an atompub-based content management system. A "collection" can have item types, e.g. "artist" and "artist work" (these item types are not predefined, by constructed runtime). We can then assert artist has (0:m) works -- we do so by posting a "relation" resource to the appropriate endpoint. Then we create relationships by attaching an atom:category to the child instance (e.g. on entry for "starry night" we add category <category scheme="http://example.com/typerel/artist/to/artist_work" term="tag:000123"/> (tag:000123 is the atom:id for entry describing Van Gogh).
Entry for van Gogh has <link rel="http://example.com/typerel/artist/to/artist_work" href="http://example.com?category={example.com/typerel/artist/to/artist_work}tag:00012e"/>
To document this, you would need to define a type-to-type relationship as:
example.com/typerel/{parent type}/to/{child type}
Is that too "meta"??
--peter keane
Re: link@rel defined by uri template?
by peter keane,
Your message is awaiting moderation. Thank you for participating in the discussion.
Come to think of it, as long as the documentation (or service description) can be generated runtime -- no need for uri templates in docs. Just documentation of the link@rel that points to the end point for creating new type-to-type relations. In AtomPub, I use app:categories to "document" the new relations as categories@scheme (which becomes a link@rel when used as I described above).
--peter keane
Re: I like REST, but I need practical framework on how to start coding
by Zubin Wadia,
Your message is awaiting moderation. Thank you for participating in the discussion.
Jean-Jacques,
I believe Michael was alluding to Microsoft Astoria...
Cheers,
Zubin Wadia
CTO
www.imagework.com
"Business Acceleration through Process Automation."
Re: Great Article
by Subbu Allamaraju,
Your message is awaiting moderation. Thank you for participating in the discussion.
Thanks. You are right about the typo. I will get it corrected.
Re: Great Article
by Subbu Allamaraju,
Your message is awaiting moderation. Thank you for participating in the discussion.
@Michael: There is a universal contract "language" for RESTful apps, and that involves the uniform interface, media types, and link relations. A client that "understands" the uniform interface, some URIs to start with, and a given set of media types and link relations should be able to function just based on these.
Document types are actually part of the uniform interface :)
by Benjamin Carlyle,
Your message is awaiting moderation. Thank you for participating in the discussion.
I agree, and would add one more correction: The uniform interface is not just a set of methods. Document types are _part_of_ the uniform interface.
In a strictly pure REST architecture, all document types would be known by all components. Because documents on the Web have essentially one function (convey human-readable information), this is essentially possible. In environments where information has different purposes (purchase order versus employee record) the near-enough interpretation is that every component understands and knows how to generate every document type that makes sense.
The service contract listed about should not describe the media type. That is the job of the architecture-wide standardisation process for the Uniform Interface. This standardisation process should result in a set of standard methods, true, but also a set of standard document types.
What is left for the service contract to describe is the contextual meaning of any URLs that you want to "pre-publish". You want clients to know where to start from in whatever activity they are involved with. Past that point, documents should provide whatever contextual information is required to continue the client's task until it is complete.
Re: Document types are actually part of the uniform interface :)
by Subbu Allamaraju,
Your message is awaiting moderation. Thank you for participating in the discussion.
@Benjamin:
Agree that media types are part of the uniform interface but not necessarily in the same way you imply. Uniform interface requires that media types make messages self-describing, but the interface itself does not have to describe what the media types are.
Secondly, whether media types are described via some "architecture-wide standardization process" or not depends on the nature of applications. As the developer, of say, some new set of HTTP APIs for some next big cool thing, I may choose to define the define media types myself. In cases where there are interoperating applications, some process like to describe may define those types. So, media types are part of the contract, and who defines those types can vary on a case by case basis.
Re: Document types are actually part of the uniform interface :)
by Subbu Allamaraju,
Your message is awaiting moderation. Thank you for participating in the discussion.
@Benjamin: Just realized that you may be referring to the uniform interface in its generic sense, where as I am using it in the HTTP sense.
Great Article, some words on WSDL's behalf...
by William Martinez,
Your message is awaiting moderation. Thank you for participating in the discussion.
For Sure, this article is one of the closest to Rest concepts I have read.
I agree with it and I think the proposed solution may be usable, practical.
Still, the WSDL comments need a little discussion. In particular, two comments made me think a little about WSDL and WS perception: first, WSDL as a violation of self-describing messages and Hypermedia as an application state engine; Second, WSDL and WS as RPC-like approach.
The main idea of all this (at last to me), is that the description of the application is not out of band, but part of the application itself. WSDL has been used as a design time description to create fixed clients. But the actual idea was to have WSDL describe a set of resources called services, at runtime. Thus, if you follow, WSDL is not just a contract, but an standard media type that has all the info and links to use the application. It contains the information to create more messages and also how those messages are sent and received.
Another misuse is the RPC interaction. Services are seen as methods you need to call, when they are actually endpoints (URLs) that receive messages with an specific media type (let's think SOAP, or even the SOAP body document), and must process them. The content of the message (its type) should be enough to determine what the server needs to do with it (that is, no method name should be needed).
What do you think?
William Martinez Pomares.
Architect's Thoughts
Hybrid aproach
by Antonio Mota,
Your message is awaiting moderation. Thank you for participating in the discussion.
I'm trying to find out to do in similar situations, and since I already have a "data-centric approach" like
Re: Great Article, some words on WSDL's behalf...
by Subbu Allamaraju,
Your message is awaiting moderation. Thank you for participating in the discussion.
@William: That is an interesting interpretation of WSDL, but looking at the stated goals in WSDL spec, I don't think WSDL was designed with such an interpretation in mind.
Re: Hybrid aproach
by Subbu Allamaraju,
Your message is awaiting moderation. Thank you for participating in the discussion.
@Antonio: That's perfectly fine, although using a link like the ones in the examples would make linking more extensible.
Correction
by Subbu Allamaraju,
Your message is awaiting moderation. Thank you for participating in the discussion.
Stefan just pointed out that the HTTP responses with 201 response code did not have the Location response header. This was an oversight. Thanks Stefan.
Subbu
Typos?
by Nicholas Gall,
Your message is awaiting moderation. Thank you for participating in the discussion.
First, excellent article Subbu. Second, two typos I think.
Shouldn't this (sorry, the comment system gets rid of all leading whitespace)
<accounts xmlns="urn:org:bank:accounts">
<account>
<id>AZA12093</id>
<link href="http://bank.org/account/AZA12093" rel="self"/>
<link rel="http://bank.org/rel/transfer edit"
type="application/vnd.bank.org.transfer+xml"
href="http://bank.org/transfers"/>
<link rel="http://bank.org/rel/customer"
type="application/vnd.bank.org.customer+xml"
href="http://bank.org/customer/7t676323a"/>
<balance currency="USD">993.95</balance>
</account>
<account>
<id>ADK31242</id>
<link href="http://bank.org/account/ADK31242" rel="self"/>
<link rel="http://bank.org/rel/transfer"
type="application/vnd.bank.org.customer+xml"
href="http://bank.org/transfers"/>
<link rel="http://bank.org/rel/customer"
type="application/vnd.bank.org.customer+xml"
href="http://bank.org/customer/7t676323a"/>
<balance currency="USD">534.62</balance>
</account>
</accounts>
be this
<accounts xmlns="urn:org:bank:accounts">
<account>
<id>AZA12093</id>
<link href="http://bank.org/account/AZA12093" rel="self"/>
<link rel="http://bank.org/rel/transfer" ********************* get rid of edit
type="application/vnd.bank.org.transfer+xml"
href="http://bank.org/transfers"/>
<link rel="http://bank.org/rel/customer"
type="application/vnd.bank.org.customer+xml"
href="http://bank.org/customer/7t676323a"/>
<balance currency="USD">993.95</balance>
</account>
<account>
<id>ADK31242</id>
<link href="http://bank.org/account/ADK31242" rel="self"/>
<link rel="http://bank.org/rel/transfer"
type="application/vnd.bank.org.transfer+xml" ********************* change customer to transfer
href="http://bank.org/transfers"/>
<link rel="http://bank.org/rel/customer"
type="application/vnd.bank.org.customer+xml"
href="http://bank.org/customer/7t676323a"/>
<balance currency="USD">534.62</balance>
</account>
</accounts>
-- Nick
A couple of observations
by Nicholas Gall,
Your message is awaiting moderation. Thank you for participating in the discussion.
Now that I've addressed the typos, I wanted to make a couple of observations:
1. Your examples drove home to me for the first time that a data architect using XML and <link> now has THREE choices for representing a constituent of an XML doc: element, attribute, and now, link. For example, in the transfer document, one could have chosen to make the "note" a link to a note resource instead of an element. It would be interesting to see an analysis of which concerns would lead to the use of which style, ie element, attribute, or link.
2. I wonder why you chose to provide a transfer both an URN identifier (represented as an XML element <id>transfer:XTA8763</id>) and a URL identifier (bank.org/transfer/XTA8763). Why not just use the URL? (I think we've covered this ground before).
-- Nick
</link>
Re: Typos?
by Subbu Allamaraju,
Your message is awaiting moderation. Thank you for participating in the discussion.
@Nick:
a. I added "edit" just to quality the link. But it does not really matter, as long as the rel name is concrete enough to tell the client the type/purpose of the link.
b. A typo.
Thanks for a keen eye.
Re: A couple of observations
by Subbu Allamaraju,
Your message is awaiting moderation. Thank you for participating in the discussion.
@Nick:
1. The choice is based on granularity and access patterns. If the server decided to inline it, but wants to tell the client the client that the inlined data could be accessed directly, it can provide a link with a self rel within that inlined element. If not, it could provide just a link making it a related/child resource. Simialarly, in the case of collections, we can think of collections containing just links to members, or include a summary+link for each member, or inline the entire member.
2. You are right. We discussed this a while ago. As I tried to illustrate at www.subbu.org/blog/2008/12/resource-identity-an... the URI in the self-link does not always uniquely identify the resource. When I say identity, I am looking from the client's point of view, which may want to store representations and need to come up with a database key. This is why Atom has an <id> and RSS has a <guid>. I just borrowed atom:id for these examples.</guid></id>
Re: Typos?
by Nicholas Gall,
Your message is awaiting moderation. Thank you for participating in the discussion.
re (a) either both account representations should have ""http://bank.org/rel/transfer edit" or neither should. As it is now, the 1st acct representation has "http://bank.org/rel/transfer edit", but the second has just "http://bank.org/rel/transfer". It makes the reader wonder why you are making a distinction.
Re: A couple of observations
by Nicholas Gall,
Your message is awaiting moderation. Thank you for participating in the discussion.
re (2): One of the things I like about Google's BIGTABLE is that it was designed to use URLs as keys. Given a commitment to "cool URIs don't change", there is no reason that URLs can't be used for database keys.
Re: A couple of observations
by Subbu Allamaraju,
Your message is awaiting moderation. Thank you for participating in the discussion.
@Nick: Re (2), the id is a URI, and a URL can be substituted as long as the app follows RFC 4287.
Re: I like REST, but I need practical framework on how to start coding
by Sreekanth Manga,
Your message is awaiting moderation. Thank you for participating in the discussion.
You may be also interested in looking to Project Jersey [jersey.dev.java.net/], a Java based implementation from SUN.
Thanks and a couple of questions...
by Mark V,
Your message is awaiting moderation. Thank you for participating in the discussion.
Fantastic article. I'm a non-IT/CS domain specialist who finds himself doing more and more programming. Your article answered a number of questions and confirmed a suspicion I hadn't yet seen a 'correct' REST description - RESTful now makes much more sense - Thank you!
Still I like some ideas in WADL:
- it is the documentation (extremely important)
- grammars
- provides an advanced starting point, even though it is not proper REST (remember my 'real-job'/domain-specialty is calling very minute)
Having said all that what you describe is very elegant and hopefully will be amenable to code-gen by some framework.
Some Questions.
In your scheme the 'rel' attribute of a 'link' element is the (only?) brittle part, i.e. if the server side code changes this data, then the client side code has to be updated (manually or automagically). The benefit of the set-up you describe is that the server code can do what it likes with the 'href' location and the client code shouldn't break, or at least not so easily. Is this a fair summary?
Next, in point 3 in your model under 'Is this practical', am I correct in thinking you'd 'create classes manually' which correspond to data in the 'rel' attribute in each link element? This 'rel' data was read in step 2 - correct?
Thanks
Mark
Re: Thanks and a couple of questions...
by Subbu Allamaraju,
Your message is awaiting moderation. Thank you for participating in the discussion.
@Mark,
Instead of URI in the href, the relation is part of the contract, and hence any changes to relations can break the contract. Imagine a web server deciding to use "myfeed" in place of "alternate" for a link to an Atom feed. That will all clients that are looking for that link.
Code generation depends on the media types that the server is supporting for each resource. If those media type specifications do have provisions for code generation, so be it. But the rel data itself may not give enough clue for a code-generation tool.
Re: Thanks and a couple of questions...
by Mark V,
Your message is awaiting moderation. Thank you for participating in the discussion.
Thanks Subbu,
OK, so I understand that this means link@rel is the contract - is this contract immutable?
That is, would it be RESTless to write a client and its server to regard rel (or rev) alone as an 'insurance' contract.
E.g Scenario: A client holds on to a response long enough for the link@rel to be invalid - so now the contract is broken. What would be regarded as RESTful behavior:
a) Have the client refresh the stale response?
b) Have the server accept an enquiry about the correct link for rel?
The second option gives some fall back behavior, but I'm not sure if anything about this violates the REST objectives. This is an issue when regenerating the stale response is very time consuming, but getting the link updated is not expensive.
In case you are interested - rubywaves.com seems to aiming at an extensible resource focused framework, although it is early days.
Mark
Re: Thanks and a couple of questions...
by Mark V,
Your message is awaiting moderation. Thank you for participating in the discussion.
Hmm, Having sketched out a client on paper I think I can now answer my own Q:
a)
Reason: Any 'insurance' contract makes no sense in REST since you cannot guarantee, from the current data, you can work out which path the client-server took to reach its current state, and that state, or at least a representation of it, may be embodied in any href's that are stale/broken.
media types
by Viviane Festjens,
Your message is awaiting moderation. Thank you for participating in the discussion.
I also think this is a very good article explaining what REST is all about.
Concerning the media types you use in the links I was wondering on how you would deal with different representations of a specific resource.
Typically you would have your account type defined by application/vnd.bank.org.account+xml.
What would you do if your service had several representations of this account, f.i. a json representation.
You could argue that once you started using xml you prabably want to continue using xml, but what if for instance you have a type within your system for which there is a standard, like iCal, xspf, ... It would probably be a good idea to also provide a resource in a standard format, like ical for a schedule or calendar. The list of schedules in your system will probably be a self defined xml type, whereas for a specific schedule you would service a specific xml type as well as an ical type.
Wouldn't it be better to just use the rel attribute and to describe for each rel attribute which media types are available in your service?
This would also make sense in the case you were building a service with several versions, i.e. your resources can have an account_1.0+xml and an account_1.1+xml representation. You could argue that once you started using version 1.0 you would continue to use the 1.0 representations. If you provide the type for each link you will probably have to have a new version for each type even if only one type changed (e.g. extra info) because all resources are linked to each other. If you would leave choosing the type up to the client, the client could decide which version he wants, choosing from the different types you specified for a certain rel attribute. If at that time he was only aware of version 1.0, he would take version 1.0, another client needing this extra info in the 1.1 version could choose this 1.1 representation. In this way you would only define one new type if only one resource had a new implementation.
Does this make sense?
RDF - a resource description language
by Bob Ferris,
Your message is awaiting moderation. Thank you for participating in the discussion.
I think you are overusing media types. As Roy T. Fielding stated once: "The media type is a generic processing model that every agent can learn if there aren’t too many of them (hence the need for standards)." (see roy.gbiv.com/untangled/2008/rest-apis-must-be-h...).
So why not using RDF, as a generic knowledge representation structure (resource description language), as a basis for describing media type specifications and typed links in a machine-processable way. The "type" attribute of a link (relation) is the defined by the range definition of an RDF property and the "rel" attribute is the specific RDF property itself. The description of the property (relation) can be retrieved by resolved the related URI.
Another statement of Roy T. Fielding is that "Every media type defines a default processing model" (see roy.gbiv.com/untangled/2008/rest-apis-must-be-h...); that means, a media type specification should include the definition of a process model for each link type that is part of the specification. Generally, media type specifications are only a specific kind of knowledge representation language. This, rules the application of HTTP OPTIONS out, because the set of possible methods that can be successfully applied on a specific link type should already be defined in the media type description. Since, a media type specification should also be processable by a machine agent, one can (/should) also define an RDF-based description. This enables a client also to learn a new media type on-the-fly, if wanted (analogous to the HTTP Upgrade header field).
An RDF-based description can of course include further more domain specific link types that are usually defined in separate vocabulary/ontology specifications that are reference in the description. The media type for RDF-based description should start with "application/rdf" and followed by the preferred serialization syntax e.g., "+xml" or "+turtle" or "+json".
Fully machine-processable descriptions of all kinds are a requirement for a true RESTful application, otherwise the constrains "self-describing message" and "hypertext as the engine of application state" are violated. The client should always be able to decide to which state he/she/it want to change next (cf. www.ics.uci.edu/~taylor/documents/2002-REST-TOI...). This is also quite good summarized by a further statement from Roy T. Fielding:
"Automated agents are dependent on their understanding of the media types, link types, or microformat extensions provided in representations. It is the same basic issue as with human communication: we will always need a common vocabulary to make sense of it. Exposing that vocabulary in the representations makes it easy to learn and be adopted by others. Some of it will be standardized, some of it will be domain-specific, but ultimately the agents will have to be adaptable to new vocabulary." (see roy.gbiv.com/untangled/2008/rest-apis-must-be-h...).
WSDL and WADL is for desribing services and applications. However, REST is resource oriented, so we like to describe resources in a generic way. We aren't interested in, whether these resources are implemented queues, services or applications. Cf.
"If a client is receiving instructions on how to interact with a resource just before acting only on those instructions, then the client doesn’t care if the resource is a distributed queue. It simply doesn’t need to know how the resource is implemented." (see roy.gbiv.com/untangled/2008/rest-apis-must-be-h...)
Finally, I haven't really seen yet an example of an application that completely matches the constraints of the REST architectural style. I also saw several requests in Roy T. Fieldings blog for such an application, however, he didn't responsed yet (AFAIK).
PS: "A REST API should not be dependent on any single communication protocol" (see roy.gbiv.com/untangled/2008/rest-apis-must-be-h...)
Generate Spring REST Documentation
by Robert Morschel,
Your message is awaiting moderation. Thank you for participating in the discussion.
IG Group have recently open-sourced their RESTdoclet solution, which is specifically aimed at services built using Spring’s REST framework. We use this internally to automatically document all our RESTful services and publish these via an internal web portal.
More info here: ig-group.github.com/RESTdoclet/
Robert @ IG Group
Re: Generate Spring REST Documentation
by Jennie Vecchio,
Your message is awaiting moderation. Thank you for participating in the discussion.
Informative post - I was enlightened by the info ! Does someone know if I can grab a blank a form form to complete ?