REST HATEOAS: How to know what to POST?
Asked Answered
B

1

7

I still don't understand how the client knows what data to POST when creating a resource. Most tutorials/articles omit this and in their examples, a client always seems to know a priori what to post (i.e. using out-of-band information). Like in this example, the consumer knows that he has to place the order by setting what <drink\> he wants.

I can only image a few approaches and I don't know if they are valid:

1. Returning an empty resource
The client discovers a link to /resource with a link to /resource/create and relation "create". A GET to /resource/create returns an empty resource (all attributes are empty) and a link to /resource/create with relation "post". The client then sets values to all attributes and POSTs this to /resource/create which returns a 201 (Created). This means that the CRUD operations are not located at the resource endpoint but to URI like /resource/create and that the client might set attributes the server ignores (like a creation date which is set on the server side)

2. Returning a form
Basically the same approach as above, despite the fact that not a resource is returned but some meta-information about what fields to post and what datatypes each attributes needs to have. Like in this example. Still, the creation endpoint is not located at /resource but on /resource/create

3. Creating by updating
A POST to /resource immediatly creates an empty resource and returns a link to this resource. The client then can follow this link to update the resource with the necessary data doing PUTs.

So what is the best approach that still follows the HATEOAs paradigm and why are all of these tutorials (and even books like REST in Practice) omitting this problem?



UPDATE:
I recently found out the Sun Cloud API seems to be pretty close to an "ideal" REST HATEOAS API. It not only defines some resources and does hyperlinking between them, it also defines media types and versioning. With all this theoretical discussion, it's pretty good to have a concrete exmaple. Maybe this helps some readers of this question.

Bahena answered 7/4, 2015 at 13:16 Comment(0)
P
6

Most tutorials and books about REST are very misleading, because there are many misconceptions about REST and no authoritative source other than Fielding's dissertation itself, which is incomplete.

REST is not CRUD. A POST is not a synonym to CREATE. POST is the method to be used for any action that isn't already standardized by HTTP. If it's not standardized by HTTP, its semantics are determined by the target resource itself, and the exact behavior has to be documented by the resource media-type.

With HATEOAS, a client should not rely on out-of-band information for driving the interaction. The documentation should focus on the media-types, not on the URIs and methods. People rarely get this right because they don't use media-types properly, and instead document URI endpoints.

For instance, in your example, everything has the application/xml media-type. That's the problem. Without proper media-types, there's no way to document resource-specific semantics when everything has the same media-type without relying on URI semantics, which would break HATEOAS. Instead, a drink should have a media-type like application/vnd.mycompany.drink.v1+xml, and your API documentation for that media-type can describe what to expect when using POST with a rel link.

Piccalilli answered 7/4, 2015 at 14:42 Comment(6)
Thanks for your reply. If I have a media type application/vnd.mycompany.drink.v1+xml the client would have to know about the media type a priori, wouldnt it? What is the difference to a regular documentation describing the resource with its attributes? And where is the media type information stored?Bahena
The client MUST know about the media-type a priori. That's the only out-of-band information the client should have, besides the entry point URI. The difference is that it focuses on the media-type, not on URI semantics. The media-type information is in your documentation, wherever you have it.Piccalilli
Ok, thanks. So if I would define my media types like in this blog (amundsen.com/blog/archives/1041) it's ok? And defining the URIs like in step two automatically means POSTing an item structure to the collction-uri leads to adding this item to the collection? Am I free in the format I define my media types? If so, I don't see why defining custom media types from a technical point of view is neccessary (e.g. using them in a @RequestMapping in a Spring Controller)Bahena
It looks good. POST never automatically means anything. If you are using POST, you have to document what it does. An API using generic media-types is never RESTful.Piccalilli
I am just confused by the fact that in the blog, the guy does not define what POST does except for saying so. If that's fine enough, ok :-) Still, why shouldn't I use application/json everywhere if I have to document the structure/media type anyway outside the code?Bahena
If you use application/json everywhere, the only thing to distinguish between your own resource types is the URI semantics, which should be irrelevant in REST. The client has to parse the URI to know what is a drink and what is a order, for instance.Piccalilli

© 2022 - 2024 — McMap. All rights reserved.