Why HATEOAS?

It started with a simple question or two, which boil down to:

  • If Hypermedia as the Engine of Application State (HATEOAS) is so cool, why is it not being used by more REST APIs today?
  • Are there any short term benefits to go along with the stated long term benefits like adaptability to change?

Here's the answer I sent back to the rest-discuss mailing list, which I've decided to memorialize by turning it in to a blog entry. Note that it was written yesterday, so the publication date (April 1) is not semantically meaningful :-).


I know exactly where you are coming from with these questions ... I felt the same way until recently. I've designed several REST APIs over the last couple of years, but up until the most recent one, I designed and documented them in the "typical" way, describing the URI structure of the application and letting the client figure out what to send when. My most recent effort is contributing to the design of the REST architecture for the Sun Cloud API to control virtual machines and so on. In addition, I'm very focused on writing client language bindings for this API in multiple languages (Ruby, Python, Java) ... so I get a first hand feel for programming to this API at a very low level.

We started from the presumption that the service would publish only one well-known URI (returning a cloud representation containing representations for, and/or URI links to representations for, all the cloud resources that are accessible to the calling user). Every other URI in the entire system (including all those that do state changes) are discovered by examining these representations. Even in the early days, I can see some significant, practical, short term benefits we have gained from taking this approach:

  • REDUCED CLIENT CODING ERRORS. Looking back at all the REST client side interfaces that I, or people I work with, have built, about 90% of the bugs have been in the construction of the right URIs for the server. Typical mistakes are leaving out path segments, getting them in the wrong order, or forgetting to URL encode things. All this goes away when the server hands you exactly the right URI to use for every circumstance.
  • REDUCED INVALID STATE TRANSITION CALLS. When the client decides which URI to call and when, they run the risk of attempting to request state transitions that are not valid for the current state of the server side resource. An example from my problem domain ... it's not allowed to "start" a virtual machine (VM) until you have "deployed" it. The server knows about URIs to initiate each of the state changes (via a POST), but the representation of the VM lists only the URIs for state transitions that are valid from the current state. This makes it extremely easy for the client to understand that trying to start a VM that hasn't been deployed yet is not legal, because there will be no corresponding URI in the VM representation.
  • FINE GRAINED EVOLUTION WITHOUT (NECESSARILY) BREAKING OLD CLIENTS. At any given time, the client of any REST API is going to be programmed with some assumptions about what the system can do. But, if you document a restriction to "pay attention to only those aspects of the representation that you know about", plus a server side discipline to add things later that don't disrupt previous behavior, you can evolve APIs fairly quickly without breaking all clients, or having to support multiple versions of the API simultaneously on your server. You don't have to wait years for serendipity benefits :-). Especially compared to something like SOAP where the syntax of your representations is versioned (in the WSDL), so you have to mess with the clients on every single change.

Having drunk the HATEOAS koolaid now, I would have a really hard time going back :-).

Comments:

[Trackback] Craig asked me how you would describe something like the Sun Cloud APIs with WADL and I thought others might be interested in the answer. A key feature of the cloud APIs is that they make good use of hypertext...

Posted by Marc Hadley's Blog on April 02, 2009 at 01:17 AM PDT #

I think this explains the benefits well, but I don't buy the 90% bugs portion. It has a smell of hyperbole. I don't remember it being that big of a deal or difficult to get right. Either way, doesn't having client side libraries also achieve 1 and 3 just as well? I'm not convinced that HATEOAS achieves these any better than those alternatives. In fact I would imagine that even with HATEOAS we'll still be creating client side libraries. So maybe this technique helps the client side library creator a little. Although, even if the server sent a set of URIs it couldn't eliminate URI parametrization which would diminish the benefits of 1 & 3. Clients will still be creating URIs, probably through more parametrization, simply because you can't represent every possible navigation without getting input from the user.

Point 2 has more teeth to it than the others. The idea that the server hasn't given the client a URI will reduce the chance of getting into a bad state has merit. But, notice it's the use of the word reduce not eliminate. I could start a VM and get a URI to that VM, but someone else might shut it down behind my back. Although I still have a URI to it. 404 anyone?

It's strange and exciting that our web services are starting to mimic HTML architecture in their interaction. We've ditched the cruft (SOAP), adopted HTTP as the lingua franca, and now we're experimenting with URIs embedded in our documents to represent states and transitions. Hmmmm now where have I seen this architecture before?

Posted by Charlie Hubbard on April 08, 2009 at 12:39 AM PDT #

Post a Comment:
Comments are closed for this entry.
About

craigmcc

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today