Why is HATEOAS important?

Asked

Viewed 9,005 times

33

I am studying REST and Web API development and I have heard about HATEOAS (Hypertext as the engine of application state). I understood the idea: when answering a request, in addition to what we normally return, the idea is also to return data on what can be done next. An example I saw on the Internet was this:

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>

In addition, I’ve read several times that doing this is very important for many things, among them to allow the API to evolve easily without breaking old clients.

It turns out I can’t understand what the real benefits are of doing this. Basically the client will not decide by itself which calls make based on these links, anyway we have to put "hardcoded" there which can be done next.

So what is the real importance of using HATEOAS and what benefits do we have from its use?

  • At the moment I cannot give a comprehensive answer, but think of a simple web page: the client (browser) may not decide for itself which calls to make, but the user can - just click on the links! The fact that web pages use HATEOAS allows both servers (i.e. the one that implements application logic, and that serves web pages according to this principle) to vary (no matter if it is Java, . NET, PHP, Python...) how much customers who consume them can also (no matter if it’s Firefox, Chrome, IE...), independently of each other. The general idea is this.

4 answers

33


The characteristic HATEOAS is, in the words of its author, "design on the scale of decades" and "many of its restrictions are directly opposed to efficiency in the short term". That is, it is something applicable to software/platforms of more general purpose, destined to survive for a long period of time, despite the evolutions of technology.

The best example of practical application of HATEOAS is the HTTP protocol, in which a variety of servers can communicate with a variety of clients, and both can evolve independently of each other. In a web application, for example, not only page structures are reported by the server (and rendered on browser) as also comes the indication of what actions are possible from that page - represented by means of Urls to be consulted (whether hyperlinks, form destinations, or something else). A change in the server (say, the inclusion of a new field on the page) does not require a change in the client, as any actions related to it will be represented in the form of hypermedia, and the browser knows how to invoke them via the HTTP protocol itself.

You are right when you say that the links should represent what can be done next. The meaning of this, however, is that it is the key point: this data + link combination represents the state system, or resource within the system. Using the same example cited, if the bank account is in the negative, then you cannot withdraw from it or transfer from it, just deposit more money into it:

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

This has at least two practical meanings:

  • The server does not need to keep track of who the client is accessing, nor what state it is in: the client itself knows that the only possible transitions are those for which a link is available;
  • Client does not need to implement any custom logic to find out which actions are possible based on the current state of the resource (ex.: check whether the balance is positive or not, and on that basis determine whether or not the withdrawal or transfer links should be displayed/enabled). The links themselves already say - by their presence or absence - what can or cannot be done.

As for their claim that "the client will not decide for itself which calls to make based on these links", in fact, it will not, at least not without some action being taken by the user. But isn’t that the only reason the server communicated with the client, to allow the user to do something? If the next call could already be determined according to some automated logic, did not need the control come to the client and he make a new request after that, it would be enough for the server itself to decide and do it right there...

hardcoding

That question of what to put hardcoded And what you leave generic is just what differentiates a long-term design from a short one. If you are developing a single server to communicate with a single [client type], then it makes no sense to use REST in principle, let alone use HATEOAS! Only if you predict that multiple clients will be developed over time, and all have to be compatible with your server, does this methodology apply.

The whole question is of evolution: whether in the specification of its client you determine that "there must be a screen to represent a bank account, with a pro number and another pro balance field, and buttons for the 'deposit', 'withdraw', 'transfer' and 'close' actions, nothing prevents multiple implementations of your client be done. However, if in the future you decide to include an "agency" field, or you will have to make it optional (not to break the clients existing) or will need to update the specification of the client (automatically making all existing ones incompatible with your version of server). The evolution of the server is linked to the evolution of the clients...

In the case of a field, as in the example above, there is no easy solution: after all, the semantics behind the represented data still needs to be agreed between clients and servers, and this has to be done "out-of-band" (as an example, each HTML tag has a precise semantics, and it is so expected that the browsers render/implement it correctly when the servers send it with a correct expectation of what will be presented to the user).

But in the case of actions, in the sense of "things that may be required later from the server", it is simpler to establish them in a generic way than to put them also hardcoded in the specification. Of course, this presumes some way to communicate to the user what the semantics of it is (a new link appeared, but what exactly does it do?). This can be done either in a generic way (a text, icon or tooltip accompanies the link) or also require a change in the client (if it is an automated tool that is consuming your REST API, there is no way out but to adapt it to benefit from the new possibility that has emerged).

Importance and Benefits

Unfortunately, I don’t have enough knowledge or experience to comment on that. The vast majority of the software we do seeks short-term efficiency, and the most common form of evolution is "throw it away and start from scratch"... Not only is it rare to have term and budget to design for the long term, but it is also relatively rare to have interest in interoperability with third party systems (my company’s server has to be accessed by client of my company! ). And when the need for an API arises, it is usually intended to power an automated process, which needs to make a decision regarding the next step to execute, and therefore a "knowledge" of the semantics behind the available actions.

For these reasons, me I personally do not see much benefit in following the REST and HATEOAS principles to the letter; perhaps with more experience in larger projects, my opinion will change, and I can give a more complete and informed answer. At the moment, I can only answer with another question: are you prepared for the moment your service evolves? How do you want to prevent all clients break even when it happens?

3

It is not a pattern that pleases me, you can be sure that implementing this will make your development at least 20% slower, also more polluted, see an implementation in Spring where you would return the pure entity, you return a "Resource" of the entity that is, has work to create a secondary class, at the time of receiving the data also receives with an extra layer, it would take longer to do and leave the code more polluted, and I do not like the idea of mixing the documentation of the API with the data being trafficked, the documentation is something that in my opinion is better to be separated in a document, generates a more pollution in your data, imagine a list with 30 data for example each with 5 links, it would be a problem to identify an error in this JSON or XML, what but it makes me go against this pattern are the benefits of it, I see no almost, example:

<link rel="close" href="/account/12345/close" /> 

Here the front would work with the parameter that is inside the HREF, a benefit would be to be decoupled from this content, if it were changed would have no modification in the client, however and if we are thinking of changing the routes of the application we would have to think that attributes can be changed also as for example instead of "close", could turn "Exit" for example, and this would be hardcoded on the client as well, would cause problem in the same way, and would further complicate the correction of the problem, the documentation would have to exist anyway, work replacing the documentation by that standard, would give much more problem than solution, and if the documentation will have to exist anyway sincerely I see no benefit in it.

There are similar things as for example for those who have worked with Web Service must know WSDL, where it is a kind of documentation of webservice, except that the utility is extreme, java has features that already converts this into classes, besides it is a file only for documentation, not mixed given with document. So today is something that I would never use in any project of mine neither in the short and much less in the long term, I think it would harm the project a lot with little benefit, but if for example they develop a solution ai ai ai a Rest hateoas and already makes a client automatically, then the thing may start to change, and the productivity begin to come with this model there, but today I would not really use, there are those who speak very well of this pattern but I really can’t.

1

What we have today in most services are wrong implementations of the concept of REST, so much so that it has a strand that tries to fix this by calling the API’s that really seek to be REST of Hypermedia API.

The error is there

Anyway we have to put "hardcoded" there what can be done next.

The server should have the freedom to manage its resources in the most appropriate way by instructing the client how to mount the URL to access a given resource (which if it is "hardcoded" can be considered as an RPC).

In a free translation of Roy Fielding’s words:

A REST API should be used without any knowledge beyond the initial URI and a set of standard media types. From this point on every state transition must be guided by the client by the choices provided by the server that are present in the representations received or implied by the user’s manipulation of these representations. Transitions can be determined (or limited) by customer knowledge of media types and resource communication mechanisms, both of which can be improved on-the-fly.

It’s a complex subject, but you can extract more information on Roy Fielding’s blog: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

--

I recommend this presentations:

And this article "No one understands REST" http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http

  • I agree! When people think of "REST API" they think of a stable API, which can be used by automated processes to perform tasks without human intervention (and which would therefore be "broken" if the API changed without warning)when originally this concept described something quite different...

0

I find this idea of HATEOAS meaningless.

If I add/change/remove an API method/url, the implementor needs to know what has changed, and how to call it, the "Client API" will not know to simply navigate the described structure. What will read this will be a system, and not a user with intelligence read a link and know what to do with it.

The BIG promise is to pseudo-document the API, however, there are much better alternatives for such a purpose.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.