HATEOAS: concise description

RestHateoas

Rest Problem Overview


I am trying to get a clear and concise understanding of HATEOAS, and I am by no means an expert WRT REST. (I think I get it though, thanks to this http://www.looah.com/source/view/2284 ).

Can anyone suggest an equally enlighenting blog/article WRT HATEOAS?

Rest Solutions


Solution 1 - Rest

The Hypermedia Constraint (formerly known as HATEOAS) is a constraint that is used to provide direction to the user-agent.

By including links in returned representations, the server can remove the burden from the user-agent of determining what actions can be taken based on the current application state and knowing who to interact with in-order to achieve that goal.

As the server has no knowledge of the user-agent's current state other than what it receives in a request, it is important that the user-agent tries to avoid using state other than the representations returned from the server. This ensures that the available actions provided by the server are based the most complete understanding of the user-agent state as possible.

A user-agent conforming to the Hypermedia constraint acts like a state machine, where state transitions are caused by following links available in the current representation. The returned representation becomes the new state.

The benefits of this approach can be a very lightweight user-agent. It requires very little code to manage state as its actions should be based purely on the received response and the link that retrieved that response. The user agent code becomes declarative and reactive, rather than imperative sequences of GET this then do this and then do that, you simply have the mechanics for following links and many instances of WHEN you receive this THEN do that.

For an example of how this works, you need look no further than your web browser and a web site that doesn't use Javascript. The browser presents you with options based on links in the HTML. When you follow that link, the browser replaces its current state with the new state retrieved when you followed the link. The back button works (or at least should) because you are retrieving the state from a link in your history. The browser should not care how you got to the page, as the state should be based entirely on the retrieved representation.

This "state management" model can be very limiting, as your current application state is based on a single server response. However, complex applications can be built by using a set of user-agents working together. This is part of what AJAX achieves in that it allows a distinct user-agent to be used to make separate requests and therefore, in effect, manage another state machine. Unfortunately, most of the time people resort back to an RPC style when they start making javascript requests, which is unfortunate considering the natural asynchrony of Javascript.

Solution 2 - Rest

HATEOAS in few words: In the data you output, refer to other resources using URIs, not IDs.

As all the short definitions, the definition I just gave is wrong on many levels, but it should make you understand what the crux of HATEOAS is.

Now, for a bit longer explaination.

The HATEOAS principle says that the state of your application should advance through hypertext links. Think of you browsing around the internet. First you have to type an address in the address bar. From that point on, your navigation advances pretty much only thanks to clicks on links: you click on a link and you end up on another page. Another click and here appears another page. How was the browser able to move you from the first page to the second to the third? It used the URLs encoded in <a> elements.

Similarly if your REST applications generates this result

<accomodation>
  <hotel info="http://example/hotel/0928374" price="200"/>
  <guest-house info="http://example/guest-h/7082" price="87"/>
</accomodation>

then the receiving application will not have to access any external sources of knowledge to know that the first hotel is available at http://example/hotel/0928374 and the second one at http://example/guest-h/7082.

On the other hand, if your application generates responses with IDs like

<accomodation>
  <hotel id="0928374" price="200"/>
  <guest-house id="7082" price="87"/>
</accomodation>

the receiving application will have to know in advance how IDs must be composed with prefixes to get the URI at which the information for each accommodation is available (for example "add http://example/ to every request, then add hotel for hotels and guest-h for guest houses"). You can see that this mechanism is similar to what happens in many DB applications but is different from how browsers work.

It is important to follow the HATEOAS principle because it allows applications to grow without drastic changes to the receiving applications. Suppose you want to change your URIs from http://example.com/hotel/0928374 to https://reviews.example.com/accommodation/0928374. If you followed HATEOAS is would be a simple change: modify the returned values and that it is: receiving applications will continue to work without any modification. If instead you had separate documentation for how to construct URI, you will have to contact all the application developers and ask them to notice that the documentation has been updated and they should change their code to reflect the changes.

Disclaimer: this is a quick answer that just scratches the surface of the problem. But if you get this you got 80% of the HATEOAS principle.

Solution 3 - Rest

This article helped me to understand it thoroughly. http://restcookbook.com/Basics/hateoas/

It is simple and elegant.

HATEOAS stands for Hypertext As The Engine Of Application State. It means that hypertext should be used to find your way through the API. An example:

GET /account/12345 HTTP/1.1

HTTP/1.1 200 OK
<?xml version="1.0"?>
<account>
    <account_number>12345</account_number>
    <balance currency="usd">100.00</balance>
    <link rel="deposit" href="/account/12345/deposit" />
    <link rel="withdraw" href="/account/12345/withdraw" />
    <link rel="transfer" href="/account/12345/transfer" />
    <link rel="close" href="/account/12345/close" />
</account>

Apart from the fact that we have 100 dollars (US) in our account, we can see 4 options: deposit more money, withdraw money, transfer money to another account, or close our account. The "link"-tags allow us to find out the URLs that are needed for the specified actions. Now, let's suppose we didn't have 100 USD in the bank, but we actually are in the red:

GET /account/12345 HTTP/1.1

HTTP/1.1 200 OK
<?xml version="1.0"?>
<account>
    <account_number>12345</account_number>
    <balance currency="usd">-25.00</balance>
    <link rel="deposit" href="/account/12345/deposit" />
</account>

Now we are 25 dollars in the red. Do you see that right now we have lost many of our options, and only depositing money is valid? As long as we are in the red, we cannot close our account, nor transfer or withdraw any money from the account. The hypertext is actually telling us what is allowed and what not: HATEOAS

Solution 4 - Rest

One issue with REST & HATEOAS is the difficulty and lack of visibility and control over the interface definition. With more traditional RPC style interaction there was usually an artefact such as an IDL or WSDL that defined the API and could be controlled and managed by the project.

With a HATEOAS the API is dynamically descoverable and it may be described as a set of behaviours (state changes). The behaviours are described in the code. The API description (WADL) is generated from the code rather than code being generated from the interface description.

Solution 5 - Rest

From my personal experience working with a HATEOAS engine, the biggest difference is the philosophy of the design itself.

If we are going to build a web application there are two approaches for it. One is the RPC Style and the other is the REST Style.

If state has to be tested in a RPC style we need to call a RPC procedure which returns a result. With such an design approach, parameters returned after the first call has to be stored on the client so that further calls can use the parameters that were returned. This simply makes the client and server tightly coupled, making the overall system stateful.

Whereas in the REST style, there is no RPC. What matters is the interactions between the client and the server. For any transition of state, the client has to interact with the server to get information. The only interaction that is fixed is the home interaction. The rest are all discovered by the client as it goes through the different interactions.

From a computer science perspective, one is procedural style and it is algorithmic. where as the REST style is a interactional paradigm. Any system that adopts interactional paradigm as the language would be delivering a HATEOAS system.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMyles McDonnellView Question on Stackoverflow
Solution 1 - RestDarrel MillerView Answer on Stackoverflow
Solution 2 - RestgioeleView Answer on Stackoverflow
Solution 3 - Resterolkaya84View Answer on Stackoverflow
Solution 4 - RestJamie BowenView Answer on Stackoverflow
Solution 5 - RestAntony gonzalvesView Answer on Stackoverflow