Wayne Conrad's Blog

home

Rails HATEOAS notes

01 Aug 2014

These are notes summarizing my research into how to fully implement REST in Rails with JSON responses. These notes do not represent actual experience. They’re just me remembering links I found useful.

Restful API

REST comes in levels, according to the Richardson Maturity Model as explained by Martin Fowler.

Level 2 is what every Rails RESTful application does.

Level 3, Means that the response indicates what further routes the client may wish to do. If the client just created an object, the response may include the routes to show or delete that object.

Level 3 is also called HATEOAS1 (wikipedia), for Hypermedia as the Engine of Application State.

Martin’s article uses XML responses with elements as defined by the ATOM publishing protocol (RFC 4287), because “ATOM … is generally seen as a leader in level 3 restfulness.”

How to get links into the JSON response in Rails

Most of this section is cribbed from Rails Dilemma: HATEOAS in XML/JSON Responses by Andy Lindeman.

Here’s an example of HATEOAS in a JSON response:

{
  "book": {
    "id":1,
    "name":"Ender's Game",
    "isbn":"0812550706",
    "purchase_url":"http://www.example.com/books/1/purchase"
  }
}

The purchase_url attribute is it. Once you’ve got a book in your hand, that’s the URI to purchase it.

Andy’s article is about how to properly architect your Rails application to do this. The issue is:

Andy describes several workarounds, but the winner looks like his option 1: Render a view/partial that builds the JSON as needed. Views do have access to route helpers.

Andy rejected option 1, but commenter Brandon Beacher explained why he thinks it’s best, and gave an example of how he’s done it. It looks like an attractive approach to me. The implementation looks simple, it doesn’t fight Rails, and his argument is compelling:

Nick Sutterer’s HAL proposal

Nick Sutterer proposes the use of Mike Kelly’s [HAL][8] protocol to encode links in the JSON response. His starting example of a RESTful JSON response differs from Andy Lindeman’s example in that it includes a rel (relation) attribute. This is the same information included in the ATOM nodes in the XML responses that Martin Fowler shows.

{"location":"desk",
 "fruits":[],
 "links":[
  {"rel":"self",  "href":"http://bowls/desk"},
  {"rel":"fruits","href":"http://bowls/desk/fruits"}
]}

After applying HAL, this becomes:

{"location":"desk",
 "_embedded":{"fruits":[]},
 "_links":{
  "self":  {"href":"http://bowls/desk"},
  "fruits":{"href":"http://bowls/desk/fruits"}
}}

I don’t know if HAL is good or not. It makes me uneasy–the responses are starting to get complicated. I don’t know if it’s as useful as it is complex.

The money quote from Nick’s article is this:

“Roy Fielding, the inventor of REST, states that your API is RESTFUL if and only if it is hypermedia-driven! In my words, that’ll mean no URL code should be hard-wired into your REST client – except for the single entry point URL.” (italics mine)


1 HATEOAS? Hate the Organization of American States?

comments powered by Disqus