One of the design patterns for REST/WOA is for the application state to be driven by hypermedia responses from the server. This requirement is known as HATEOAS (Hypermedia As The Engine Of Application State).
One of the benefits of this design pattern is that the URI structure is completely decoupled from the user agent as all URIs are discovered by inspection. Depending on cababilities, it can also be used to encode how new resources are represented when submitted to the server. This means that the server can evolve much more freely while remaining backwards compatible. Another benefit is that the server can embed enough information into the response to minimize the amount of state that needs to be tracked by the server. The less state is required on the server, the more cost effectively the application can scale.
Now when it comes to hypermedia, there are various levels of capabilities. This article is a first attempt at categorizing hypermedia types according to their expressive power. The categorization is based on CRUD capabilities, or Create, Read, Update, and Delete. This seems like a good initial starting point.
Hypermedia of R Type only describe how user agents can read additional resources. RSS falls into this category.
For example, the following RSS feed (taken from Wikipedia's entry about RSS) embeds several read only links. The first one links to the RSS feed itself <link>http://liftoff.msfc.nasa.gov/</link>. The second one links to the first item of the feed <link>http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp</link>. RSS defines that links can only be used with HTTP GET to retrieve additional information. However, there is no defined way in RSS to tell a user agent how to create, update, or delete an entry. Also note that the content type of the response when doing a HTTP GET on a link is not know ahead of time.
<?xml version="1.0"?> <rss version="2.0"> <channel> <title>Lift Off News</title> <link>http://liftoff.msfc.nasa.gov/</link> <description>Liftoff to Space Exploration.</description> <language>en-us</language> <pubDate>Tue, 10 Jun 2003 04:00:00 GMT</pubDate> <lastBuildDate>Tue, 10 Jun 2003 09:41:01 GMT</lastBuildDate> <docs>http://blogs.law.harvard.edu/tech/rss</docs> <generator>Weblog Editor 2.0</generator> <managingEditor>email@example.com</managingEditor> <webMaster>firstname.lastname@example.org</webMaster> <ttl>5</ttl> <item> <title>Star City</title> <link>http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp</link> <description>How do Americans get ready to work with Russians aboard the International Space Station? They take a crash course in culture, language and protocol at Russia's Star City.</description> <pubDate>Tue, 03 Jun 2003 09:39:21 GMT</pubDate> <guid>http://liftoff.msfc.nasa.gov/2003/06/03.html#item573</guid> </item> </channel> </rss>
Hypermedia of RUD Type describe to user agents how to read, update, and delete resources. Atom, and its protocol AtomPub, fall into this category.
For example, the following Atom entry (taken from RFC 5023 - The Atom Publishing Protocol) contains a link that allows a user agent to retrieve, update, and delete the entry, using HTTP GET, PUT, and DELETE, respetively. These links are identified by having the attribute rel="edit" on their element. If the attribute had been
rel="self" instead, then a user agent would know that only HTTP GET can be use on the URI. In addition, AtomPub also specifies that the response to a GET on this URI must be an Atom document again. An Atom entry can also describe other available representations by using the
rel="alternative" with an optional type attribute, such as
<?xml version="1.0"?> <entry xmlns="http://www.w3.org/2005/Atom"> <title>Atom-Powered Robots Run Amok</title> <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> <updated>2003-12-13T18:30:02Z</updated> <author> <name>John Doe</name> </author> <content>Some text.</content> <link rel="edit" href="http://example.org/edit/first-post.atom" /> <link rel="alternate" type="text/html" href="http://example.org/first-post.html"/> </entry>
Atom also provides guidelines for how to extend the Atom format. However, for a user agent to take advantage of such extensions, it must know of them ahead of time. For instance, in the Google GData API, it is not possible for a user agent to create a new Atom entry in a Calendar feed without knowing the extension ahead of time.
Hypermedia of CR Type describe to user agents how to create and read resources. Basic (X)HTML falls into this category.
The following (X)HTML document (taken from Forms in HTML documents) tells a user agent how to create the representation of a resource and submit to the server using HTTP POST. Note that (X)HTML only allows two representations for submit operations:
multipart/form-data. In other
words, it is not possible to instruct a user agent to submit an XML representation with a HTTP POST request.
<html xmlns="www.w3.org/1999/xhtml/"> <head> <title>Add User Form</title> </head> <body> <form action="http://somesite.com/prog/adduser" method="post"> <p> First name: <input type="text" name="firstname"><br> Last name: <input type="text" name="lastname"><br> email: <input type="text" name="email"><br> <button name="submit" value="submit" type="submit">Send<img src="/icons/wow.gif" alt="wow"></button> <button name="reset" type="reset">Reset<img src="/icons/oops.gif" alt="oops"></button> </p> </form> </body> </html>
Similarly, the form element can be used to tell user agents how to construct URIs when submitting a request using HTTP GET. The
<a href="..."> element tells a user agent that the link can be used with HTTP GET.
Hypermedia with +COD Extension is capable of loading custom code into user agents. This capability is known as Code-On-Demand. Since having this capability has no prerequisites on the category of the hypermedia type, it seems most natural to cite it as an extension. (X)HTML has this capability, making it a CR+COD type.
multipart/form-data representations defined by basic (X)HTML.
This article presented a categorization of known hypermedia types with concrete examples. The categorization is a first attempt at establishing a scale for hypermedia and its expressive power. The hope is that by better understanding the various capabilities available, that REST/WOA architects can choose the right hypermedia type for their applications.