HATEOAS and POST method

2,642 views
Skip to first unread message

Kumar Mani

unread,
Sep 19, 2013, 11:15:26 PM9/19/13
to api-...@googlegroups.com
Hey All,

I am constructing my first Restful API. I have a resource "customer details" for which a GET is exposed. When I return the details, I would like to include select URIs in my response to enable customers to update (email address for example). Since it requires couple of other fields in addition to email address in the request and the fact that it's the same resource "customer details", POST operation seems to be the right choice. So, even with the HATEOAS link it cannot be used "as-is" and it requires the internal knowledge of my API.
Is this the limitation of HATEOAS ? OR is there a way around this ?

Thanks !

Jørn Wildt

unread,
Sep 20, 2013, 3:43:30 AM9/20/13
to api-...@googlegroups.com
Hmm, what do you mean by "select URis"? And what do you mean by "So, even with the HATEOAS link it cannot be used "as-is" and it requires the internal knowledge of my API."?

If you are interested, then I wrote a piece about partial updates here: http://soabits.blogspot.dk/2013/01/http-put-patch-or-post-partial-updates.html

/Jørn


--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft.
For more options, visit https://groups.google.com/groups/opt_out.

Dietrich Schulten

unread,
Sep 20, 2013, 6:59:57 AM9/20/13
to api-...@googlegroups.com

A basic assumption is that the same resource "customerdetails" can be requested with a GET, and updated with a PUT, by sending an edited version of the resource representation,  OPTIONS is used to allow PUT. So in the simplest case, in order to allow editing, you do not add links, but you just support PUT and accept the content type you were sending out on the same resource, applying the changes you find in the PUT request. Things become more complicated if you must place restrictions on the PUT body, for instance if you have fields with allowed value ranges, read-only portions etc. and you want to tell the client about that.
Content types are the key here. The content type can define the expected data format for a client that needs to edit data.
Xhtml is the only standardized content type which has built-in support for such a thing through forms. A number of standardization efforts are underway, which try to establish well-known content types and profiles to tell the client about expected input. The profile can be attached through a link rel, a Link header or a content-type parameter if the content type explicitly says so; note that application/json does not allow that.
Hal, Siren, collection+json, json-hyperschema, atompub, json-ld and Hydra are the approaches I find most interesting. Some of them explicitly define editing facilities and conventions. Bottom line: look into content types and profiles.
But make sure that you do not publish your server internal types via the profile :-)
Best regards,
Dietrich

--

erewhon

unread,
Sep 20, 2013, 11:38:22 AM9/20/13
to api-...@googlegroups.com
I wouldn't consider this a limitation of HATEOAS but a design problem.  You could expose a separate resource whose representation is the template for publishing the POST data, though I think the common approach here is to provide documentation to cover POST semantics.

Mike Kelly

unread,
Sep 20, 2013, 12:01:11 PM9/20/13
to api-...@googlegroups.com
Yep, you should somehow attempt to make the link's documentation
discoverable from the contents of the message itself. The best way of
doing this is to use a URL for the link relation, so that the name of
the link and the location of its documentation are one and the same
thing.

One of the downsides to this is that URLs tend to be relatively long
strings and not very readable keys. In hal+json we've tackled this by
introducing 'compact URIs' (or 'curies' for short), this allows you to
have short, readable link relations that are still expandable into
full URLs:

{

}

Cheers,
M
> --
> You received this message because you are subscribed to the Google Groups
> "API Craft" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to api-craft+...@googlegroups.com.
> Visit this group at http://groups.google.com/group/api-craft.
> For more options, visit https://groups.google.com/groups/opt_out.



--
Mike

http://twitter.com/mikekelly85
http://github.com/mikekelly
http://linkedin.com/in/mikekelly123

Mike Kelly

unread,
Sep 20, 2013, 12:06:20 PM9/20/13
to api-...@googlegroups.com
Apparently, my example of curies got eaten;

{
_links: {
"curies": [{
name: "ex",
href: "http://example.com/docs/rels/{rel}",
templated: true
}],
"ex:widget": { href: "/widget" }
}
}

The "ex:widget" link in the above doc expands to
http://example.com/docs/rels/widget

Cheers,
M

Alex Soto

unread,
Sep 22, 2013, 2:25:25 AM9/22/13
to api-...@googlegroups.com
This is why I like siren's actions.  http://sirenspec.org

Kumar Mani

unread,
Sep 23, 2013, 10:35:05 PM9/23/13
to api-...@googlegroups.com
Sorry it took me a while to answer some of the follow up questions.

Let's say I have exposed the Customer details in this API : http://www.api.mycompany.com/customer/details. This supports GET.

Now coming to the use case described below, I return the following for a typical GET

<response>

<address-line-1>123 Main Street</address-line-1>

<city>San Diego</city>

<Zip>90510<Zip>

<email>som...@somedomain.com<email>

<email-update>http://www.api.mycompany.com/customer/details<email-update>

<response>


For the Email updates, I cannot just use the link as is as it requires  new email address and any other customer identification parameters such as Customer Id (which should be set in the body). So, in this case, even though the the design supports HATEOAS, I cannot programmatically use the link. The consuming developers should be aware of the input of such PUT or POST function.


That's why I was of the opinion that this may be the limitation of HATEOAS. In a simple world of "GETs", one can implement HATEOAS, but may not be when updates are expected.


Love to know the thoughts of folks of this forum.


Thanks !


On Thursday, September 19, 2013 11:15:26 PM UTC-4, Kumar Mani wrote:

Ryan Hiebert

unread,
Sep 23, 2013, 11:15:14 PM9/23/13
to api-...@googlegroups.com
As a quick way of thinking about it, I look at what HTML does for this case. It creates a form, complete with inputs and action targets. There are some media types that support forms or some analog to forms, and any that lack it, to the best of my knowledge, really aren't able to do a full HATEOAS design.

You're right, links alone are really only good for GET ing related resources. A good media format (my favorite ATM is siren) needs to have some kind of form/action representation as well.

Ryan

Mike Kelly

unread,
Sep 24, 2013, 2:56:34 AM9/24/13
to api-...@googlegroups.com


On 24 Sep 2013 04:15, "Ryan Hiebert" <ry...@ryanhiebert.com> wrote:
>
> As a quick way of thinking about it, I look at what HTML does for this case. It creates a form, complete with inputs and action targets. There are some media types that support forms or some analog to forms, and any that lack it, to the best of my knowledge, really aren't able to do a full HATEOAS design.
>

tl;dr: forms - YAGNI. If you're building a GUI and you "want to do forms", you should probably be looking at HTML - if not, you probably don't need forms.

Afaik there's no such thing as "full HATEOAS design" but even if there was, forms would not be a requirement. HATEOAS means clients progress through an application via control elements in the messages, there is no hard requirements as to what these control elements must be.

If the clients you are targeting are coded machines (I.e. not humans) then the types of control you need to afford them will look very different because they are very different in nature and have very different capabilities. Comparing the use of hypermedia in an API to the use of HTML in GUIs only really makes sense to demonstrate the principal of hypermedia, not to set a yard stick in terms of required hypermedia affordances.

If you bring dynamic control elements like forms into your API then you're doing 2 things that are (imo) counter productive:

1. Making your raw messages more complicated and difficult to deal with.
2. Assuming (or worse, requiring) that machine clients will be able to react intelligently to the kinds of dynamic change your controls allow.

The reason forms work so well in web apps is because humans are highly adaptable. Machines aren't adaptable because (for the most part) they're coded to perform a very specific, pre-defined dance. That dance is actually encoded into them by a developer - so the capability of a machine to handle any given transition is a result of what the developer was able to understand about the API... machine-readable forms are not a good vehicle for this because they're more cumbersome and less effective than writing it down in plain language.

Cheers,
M

Mike Kelly

unread,
Sep 24, 2013, 3:05:40 AM9/24/13
to api-...@googlegroups.com


On 24 Sep 2013 03:35, "Kumar Mani" <mkumar...@gmail.com> wrote:
>
> Sorry it took me a while to answer some of the follow up questions.
>
> Let's say I have exposed the Customer details in this API : http://www.api.mycompany.com/customer/details. This supports GET.
>
> Now coming to the use case described below, I return the following for a typical GET
>
> <response>
>
> <address-line-1>123 Main Street</address-line-1>
>
> <city>San Diego</city>
>
> <Zip>90510<Zip>
>
> <email>som...@somedomain.com<email>
>
> <email-update>http://www.api.mycompany.com/customer/details<email-update>
>
> <response>
>
>

> For the Email updates, I cannot just use the link as is as it requires  new email address and any other customer identification parameters such as Customer Id (which should be set in the body). So, in this case, even though the the design supports HATEOAS, I cannot programmatically use the link. The consuming developers should be a ware of the input of such PUT or POST function.
>

Change the link to look like this:

<link rel="http://api.mycompany.com/rels/email-update" href="http://api.mycompany.com/customer/details" />

And from http://www.api.mycompany.com/customer/details serve a web page that explains what content can be POSTed.

This is hypermedia and its fully discoverable from within the message!

Cheers
M

Mike Kelly

unread,
Sep 24, 2013, 3:09:16 AM9/24/13
to api-...@googlegroups.com


On 24 Sep 2013 08:05, "Mike Kelly" <mikeke...@gmail.com> wrote:
>
> And from http://www.api.mycompany.com/customer/details serve a web page that explains what content can be POSTed.
>

Typo, this should have been http://api.mycompany.com/rels/email-update

Cheers,
M

Reply all
Reply to author
Forward
0 new messages