Say it Again: CRUD is not REST

After watching the presentation CRUD is not REST – Hypermedia for Y’all! by Nick Sutterer (also known for Apotomo) I was delighted to see mention of all the parts of REST that I find myself repeating most frequently:

  • Representations of resources should be uniform
  • Use hypermedia—not URL schemes or resource name mapping—to represent relationships
  • Use a single entry to an API, hyperlink from there
  • Include a “self” link in your representations
  • REST doesn’t just mean spitting out ActiveRecord models as JSON

I haven’t tried his gem, Roar, but I’ve implemented a few RESTful Sinatra-based APIs and tried to follow the principles, despite some of the misconceptions the Web has propagated. (I remember being a little nonplussed when Rails added its “RESTful” routes.)

Having used a simple $ref key for URLs before, I really like Nick’s suggestion for more semantically-rich links in JSON:

{"id":       1,
 "links": [
  { "rel":  "self",
    "href": "http://orders/1" },
  { "rel":  "beers",
    "href": "http://orders/1/beers" }

With a disclaimer, Nick mentions that he doesn’t think you should use HTML for REST APIs. I politely disagree with such a rule, even though I much prefer JSON or XML. I think HTML parsers and CSS selector libraries have progressed to a point that it could be just as traversable to use HTML+CSS representations. The benefit of course is the same representation for browsers and clients. The downside is that most of the content of a representation would be cruft for the benefit of browser rendering and interaction. A further downside is that it requires much more effort and complexity to extract meaning, requiring a full-stack user agent.

The points about uniform resource access are critical, as we see in Roy’s dissertation:

The central feature that distinguishes the REST architectural style from other network-based styles is its emphasis on a uniform interface between components. […] Implementations are decoupled from the services they provide, which encourages independent evolvability. The trade-off, though, is that a uniform interface degrades efficiency, since information is transferred in a standardized form rather than one which is specific to an application’s needs. The REST interface is designed to be efficient for large-grain hypermedia data transfer, optimizing for the common case of the Web, but resulting in an interface that is not optimal for other forms of architectural interaction.

Here, Roy notes some of the important trade-offs when choosing the REST style, namely between efficiency and evolvability. Some excellent thought on that section and the other REST interface constraints can be found in this post from 2010 about REST.

The point about hypermedia is also important. Check a response from your RESTful API. Does it consist largely of href’s to other resources or state transitions? If not, you may have missed the importance of hypermedia to the REST architectural style, sometimes abbreviated as HATEOAS: “Hypermedia as the engine of application state.” This means that state transitions aren’t generated by clients guessing that if they can GET /orders/1 that they can also POST /orders/1/pay. That information should be included in the representation of the order, by means of a hyperlink. This means that the links always define the entire API and each of its resources, without relying on additional protocols. It also means that the API is discoverable, even if less efficient to traverse.