HATEOAS as Pictures

HATEOAS as State Machines

HATEOAS (Hypermedia As The Engine Of Application State) is an essential part of REST. The application state part leads some to explain REST and HATEOAS using state machines. While this is technically correct, I really don't like the idea of explaining REST as a state machine. People's eyes glaze over immediately when you merely say state machine. The argument roughly goes like this:

1) If I make real applications with REST, then I must use state machines
2) I have made real applications without using state machines
3) Therefore I can make real applications without REST

State machines seem to be looked at as impractical by many for design purposes. While I don't know if I agree with this statement, I think there is a need to explain things to people who hold the above argument.

HATEOAS as Pictures

Explaining HATEOAS as pictures seems more helpful to me. Imagine taking a picture of a small college administrative office. In the office, there are a bunch of applications from students on the desk in the inbound folder. Right next to the inbound folder, there are two folders labeled "outbound-accepted" and "outbound-rejected." Also on the desk is an official course listing along with a rolodex labeled "Professors."

In that picture you have a significant amount of information about the college. There is a small problem here though. What can trigger the adding of a new application into an inbound or outbound folder? That might be someone bringing in an application letter. What is it that triggers a new rolodex entry? Most likely a new professor joining the staff. Even though we can envision these actions, it's hard to see these events in pictures.

HATEOAS events

One simple thing you can do is ask yourself "What all could cause a change in this picture?," and list what you find. Notice I said what can cause a change, not what changes. You already have everything that actually changes explicitly in the picture.

Once you have a list of causes (or you could call these 'events' or 'transitions') and a list of entities (you can call these 'resources') in the picture, you can start making a true RESTful API. For every entity (resource) you'll have a bunch of causes (transitions) that apply to it. You can arrange these like so:

Entity Inbound Box Inbound
Outbound Box - Accepted Outbound -
Outbound Box - Rejected Outbound -
Rolodex Rolodex

Each column of that table is a picture. For instance, after a new application event happens, the inbound box will have a certain look, so will the outbound boxes, and even the rolodex. This is the case even though nothing but the inbound box can be affected by the new application event. Those other entities continue to exist so this still makes for a coherent picture.

All you have to do from here is transcribe your pictures into html and http. How do we do this? Well here is a representation of an inbox with the "new application", "Accept Application", and "Reject Application" events embedded inside of it:

<!-- Representing a list of college applications -->
<div id="Inbox">
  <a rel="new-application" href="..."
      title="Create new application">New Application</a>
  <ul class="all">
      <span class="student-application">John Smith's application</span>
      <a rel="accept" href="..." title="Reject John's application">Accept</a>
      <a rel="reject" href="..." title="Accept John's application">Reject</a>
      <span class="student-application">Jane Smith's application</span>
      <a rel="accept" href="..." title="Reject Jane Smith's application">Accept</a>
      <a rel="reject" href="..." title="Accept Jane Smith's application">Reject</a>

The above html represents the idea of a list of applications (the inbox), and what you can do with that list (the events affecting the inbox). In this example you have the ability to add to the list (new application), or decrease the list (accepting or rejecting a list moves the application out of the inbox and into an outbox). The entities translate into html blocks, while the events translate into link relations.

What does all of this mean?

It means you can design applications in many ways according to what you need. It also means that there is no need to write REST off because it has a constraint that requires the use of state machines.

This article was originally published on wwatson.net