Hypermedia as the Engine of Application State

One of the least well understood core tenets of the REST architectural style is that “hypermedia is the engine of application state”. Which basically means that responses from the server will be documents that include URIs to everything you can do next. For example, if GET a blog post the response document will have URIs embedded in it that allow you to create a comment, edit the post and any other action that you might want to do. Basically, this allows you to think of your application as a state machine with every page representing a state and links representing every possible transition from the current state.

This approach means that to correctly be access your application the only things a client needs to know is a) a well know starting point URI and b) how to parse one of the document formats (representations) your application supports. For human facing web applications this approach is the one that is always used. Browsers understand how to parse HTML and extract the links to the next action and the user provides starting point URIs. This has become so ingrained in the industry’s culture that most people never really even think about it in these explicit terms.

However, I am now working with a system in which there are many independent automated processes which interact with each other. It was not immediately obvious to me, or my colleagues, that we should be following the same pattern even when there are no humans involved. After all, a program can easily remember how to construct a URI from a couple of pieces of information that it knows. In fact, URI construction is almost always easier to implement than the REST approach of requesting a well known resource, parsing the returned representation and extract the URI you want.1

After pondering this for a while I did reach the, rather unsurprising, conclusion that Roy Fielding is correct and that hypermedia should be the core of our distributed application. My epiphany came when I decided that I really wanted to change the shape of a URI. I realized that if the system were only slightly bigger (and it will get there soon) there would be the strong probability that I would not know all the places that accessed the resources whose URIs I wanted to change. Therefore, I would not be able to change the shape of those URIs.

A URI that is constructed by a client constitutes a permanent, potentially huge, commitment by the server. Any resource that may be addressed by the constructed URIs must forever live on that particular server (or set of servers) and the URI patterns must be supported forever.2 Effectively, you are trading a small one time development cost on the client side for an ongoing, and ever increasing, maintenance cost on the server side. When it is stated like that it becomes obvious that URI construction introduces an almost absurd level of coupling between the client and server.

With a truly REST based architecture you are free to change just about anything about the disposition and naming of resources in the system, except for a few well known start point URIs. You can change the URI shapes (for example, if you decide that you really hate the currently scheme). You can relocate resources to different servers (for example, if you need to partition you data). Best of all, you can do those things without asking any ones permission, because clients will not even notice the difference.

Using hypermedia as the engine of application state has the effect of preserving the reversible for a huge number of decisions that are irreversible in most other architectural styles. As the section 9 of “The Pragmatic Programmer” points out, reversibility is one of the goals of any design should strive for. No one knows for sure what will be needed in the future, so having the ability to easily change your mind is invaluable. Particularly when it can be had so cheaply.


  1. It can get even more off-putting. Just imagine a situation where you would need to request several intermediate resources before you get to the URI of the resource for which you are looking.

  2. You could setup redirects/rewrites or proxy the requests if you really needed to move the resource but for high volume URIs having to redirect or proxy would probably eat a significant part the benefits you would get from moving the resource. Worse, though, is the fact that those remedies increase the maintenance requirements significantly because then you have to administrate both the real resources and the redirection/rewriting or proxying rules.

Comments 2

  1. Randy Wilson wrote:

    I’ve got a situation where we have a billion resources (data extracted from genealogical records) that need long-lived IDs so that people in our “tree” can point back at the people extracted from our “sources”.

    If we change our root URI, all the links bust. If our clients use “base URI + id” to construct URIs, then when we change, at least they just have to change the base URI instead of having to fix up a billion stored links (since the stored IDs would not have changed, though the URI did). [BTW, we’re looking at using something similar to “ark” to resolve broken links from the ids using a namespace at the beginning of the and a “resolver” service].

    When the clients are only using URIs temporarily, then it makes sense for them to get those full URIs from the server on the fly. But if they are storing them, then I’m still struggling with the best approach.

    Posted 22 Oct 2008 at 11:20 am
  2. Peter Williams wrote:

    Mr Wilson,

    I think in the situation you describe using URIs as the IDs is really compelling. The redirection capability of HTTP can be leveraged to provide excellent forward compatibility.

    If your future URI revamp is so simple that the clients would be able to handle, you could implement a simple mod_rewrite rule on the server and not have to mess with the clients at all. If however you ever need to revamp the URI patterns is some really fundamental way you can create, as part of the migration, a mapping between the old URIs and the equivalent new URIs.

    That combined with a client that respects the redirect type and you have a really scalable system. By that I mean, any client that stores URIs should updated them if it ever gets a permanent redirect when requesting that URI. If the client has some URI and a year later makes a GET request against it and receives a 301 “Moved Permanently”, it would updated that replace the old URI with the new URI in it’s internal storage.

    These mechanisms mean that you do not need a non-standard, or out-of-band, way to communicate URI pattern changes to the clients.

    Posted 22 Oct 2008 at 3:32 pm

Trackbacks & Pingbacks 13

  1. From Peter Williams - The power of hypermedia remains non-obvious on 12 Oct 2007 at 11:22 am

    […] The more I work with REST based architectures the more enamored of hypermedia. Links make your representations brightly lit, well connected spaces and that will benefit you application in ways you probably have not even imagined yet. […]

  2. From Hypermedia As The Engine Of Application State « Ka anyi kwuo okwu on 17 Feb 2008 at 3:03 pm

    […] Here is another good article by Peter Williams addresses this. […]

  3. From Peter Williams - Versioning REST Web Services on 12 May 2008 at 11:53 am

    […] has to mung all the URIs it has stored to the point at the new API. Munging all the URIS breaks the HATEOAS constraint of REST and supporting multiple versions of the API is a maintenance […]

  4. From links for 2008-05-17 « Object neo = neo Object on 17 May 2008 at 5:31 pm

    […] Peter Williams – Hypermedia as the Engine of Application State (tags: restful webservices architecture) […]

  5. From The Hypertext Constraint at Analysis from the Bottom Up on 05 Sep 2008 at 4:41 pm

    […] Peter Williams on The Hypertext Constraint […]

  6. From Refactoring Mockingbird: Hypermedia as the Engine of Application State - Troy Gilbert on 13 Oct 2008 at 10:34 pm

    […] Peter Williams – Hypermedia as the Engine of Application State. […]

  7. From Peter Williams - Vertical Slicing on 12 Jul 2010 at 9:39 am

    […] design can introduce excessive coupling which will eat up most of the advantages described above. Hypermedia – or more precisely, following the REST architectural style – is the best way i know to […]

  8. From Cookies and the RESTful API « Mike Pearce – blog on 24 Aug 2010 at 10:26 am

    […] point to your entire API and from there, they can navigate the whole damn thing. Many people have blogged on this (including the big man himself), so I shan’t go into it right now, take a look at […]

  9. From REST的资源定位 – Fan's blog on 30 Aug 2010 at 3:48 am

    […] 对于一个Web应用,URI是很重要的一部分,这包括他的schema定义、URI的build以及路由,涉及到web开发的方方面面。REST里面有个概念:hypermedia as the engine of application state。以上面的例子为例,hypermedia指的是server端返回的一个指向书详细信息的link,这个link是在server端construct的,client端拿到这个link后,就知道下一步跳转的方向,这样flow运行下去。整个应用就如同一状态机一样,从一个状态跳到另外一个状态。如果拿到的比如是孤立的信息,比如aLibery和aBookId,这时候客户端就要知道如何build link,而这一般都不是很容易的事情,也增加了系统的耦合度。而server端build href后,URI schema变化的代价就更小。这样我们就不必拘泥于web 2.0所说的:一个href应该永远可以访问。 […]

  10. From Quora on 23 Feb 2012 at 8:12 pm

    What are some guidelines to build a good RESTful API?…

    To begin with, the term REST has unfortunately been hijacked to the point where it’s hard to know what someone might be referring to when they use it. I am going to assume we’re talking about REST as Roy Fielding meant it when he coined the acronym. …

  11. From Notes on RESTful APIs – wooptoo on 17 Apr 2012 at 12:29 am

    […] Hypermedia as the Engine of Application State […]

  12. From Linking data in XML and HATEOAS « The Web and all that Jazz III on 20 Jun 2012 at 3:49 pm

    […] on a concept called HATEOAS. It is a design constraint of REST that gets overlooked as using hypermedia as the engine of application state. Given that idea, here’s the punchline: Why don’t we link data directly from within […]

  13. From Confluence: Web CMS on 30 Oct 2012 at 7:53 am

    Web Service Architecture…

    Scope This document is not meant for purely “internal” web services where both the client and the server can change at exactly the same time. However even “just to Javascript” is still an “external” client since browsers may have cached the JS……