DEV Community

Ivan Šarić
Ivan Šarić

Posted on

REST API with HATEOAS: Too many calls?

Hello,

I started learning about REST APIs designed around the HATEOAS principle and
I am trying to picture what it would be like to use it in production.
My main concern is CRUD operations on entities that are part of relations, be they one-to-one, one-to-many, many-to-many or many-to-one. Following what I understand about HATEOAS, it seems that creating/updating an entity and assigning a relationship to it are designed to be two separate calls to the REST API.
What if a clients connection breaks in between the two calls?

Doesnt this present a problem with data consistency?

For example, imagine a webshop application that allows the user to create reviews for products and assign a score. Besides the rating itself, a review entity would have a user (the creator) and a product, both as one-to-many relationships.
In this example, the client would make one call to create the review entity itself, one call to assign the user to that review and another call to assign a product to that review. In between any of those calls, the user client could crash or be cut of from the network. This would leave us with a review with no creator or worse, a review that does not belong to any product and is just cluttering our production DB.

Please write your thoughts and let me know if I misunderstood the concept.

Discussion (3)

Collapse
fnh profile image
Fabian Holzer • Edited

REST doesn't require resources to be created in that way you described. Let me quote two statements from Roy Fieldings dissertation:

REST components perform actions on a resource by using a representation to capture the current or intended state of that resource and transferring that representation between components.

and

Component interactions occur in the form of dynamically sized messages. Small or
medium-grain messages are used for control semantics, but the bulk of application work is accomplished via large-grain messages containing a complete resource representation.

Let's stay with your example: a user wants to review a product.

The review consists of a rating, a review text and the reviewer.

The review of a product would be done, by sendig a POST request to "shop/products/{productId}/reviews", with the body containing a representation of the resource to be created (the review), for example:

{
  "user": 123,
  "rating": 5,
  "review: "Absolutely fantastic product..."
}


`

The response would be, "201 Created" with the Location header set to the URL which identifies the new review, e.g. "shop/products/{productId}/reviews/{reviewId}", from which you could retrieve the review again via a GET request.

Now, what I described here, is not full fledged HATEOAS, since the client would need to know how to build the URL and what the messages look like. For that, there exist solutions like SIREN and HAL, which are formats to provide these information as well, so that apart from the entrypoint nothing needs to be known on the client side. The actions to be performed would, could are represented as links, which are provided as part of the representation of the resources. But that, i think, is a topic on its own.

Collapse
isaric profile image
Ivan Šarić Author

Thanks for the thorough and interesting explanation. I didn't mean to imply that REST in general would lead only to fine grained calls. I'm trying to understand HATEOAS setup. One thing that is still not clear to me is: How is the linkage to the user being done? Wouldn't we also need to call a url to link the user to the review? How does HATEOAS function when an entity has multiple relations?

Collapse
fnh profile image
Fabian Holzer

How is the linkage to the user being done? Wouldn't we also need to call a url to link the user to the review?

Well, I operated under the assumption, that the user is authenticated and the client knows e.g. the users id and thus is able to build a representation, which contains enough information to create the actual resource.

In a HATEOAS scenario, if you authenticate yourself, the server knows who you are. The server then would send a representation of the product which would include a description on how to build the request for reviewing the product, where the userId might be preset, be it in the path, in the query or as part of form data. And if you don't authenticate yourself, the server would just not offer you the information that there is a review action possible (assuming the business rule is, that only authenticated users may review a product).