dracoblue.net

HTTP method hints in media types considered harmful

If you are working on a new API for one of your projects, you might consider a media type like HAL or Collection+JSON as an option for structuring your API responses.

First of all, check out api-craft mailinglist or hal-discuss mailinglist for really good ontopic discussions about api architectures and media types.

Common JSON media types do not support a method parameter on relations

In HAL relations are defined in links, like this (e.g. self and http://example.org/rels/appointment/cancel):

{
     "_links": {
       "self": { "href": "/appointment/123" },
       "http://example.org/rels/appointment/cancel": { "href": "/appointment/123" }
     },
     "patient_id": "jsmith"
   }

Even though the relations for a patient appointment are available, it's not clear which http method to use.

Martin Fowler says on RMM: Level 3 - Hypermedia Controls:

The links give client developers a hint as to what may be possible next. It doesn't give all the information: both the "self" and "cancel" controls point to the same URI - they need to figure out that one is a GET and the other a DELETE.

Mike Kelly replies on "Why no methods in HAL?":

The idea is the available methods can be conveyed via the link relation documentation and don't need to be in the json messages.

@nicknovitski asked on hal-discuss, if you can add a method attribute for each rel:

{
     "_links": {
       "self": { "href": "/appointment/123", "method": "GET" },
       "http://example.org/rels/appointment/cancel": { "href": "/appointment/123", "method": "DELETE" }
     },
     "patient_id": "jsmith"
   }

But then you will end up with the question: What if there are multiple methods supported? Isn't the OPTIONS and HEAD method generally supported?

It becomes more difficult, if the HTTP method needs some additional Headers to be send (e.g. the Link-header for LINK HTTP method):

UNLINK /images/my_dog HTTP/1.1
Host: example.org
Link: <http://example.com/profiles/sally>; rel="tag"

That's why: Don't do it. Use the Allow-Header instead.

Conclusion: Use the Allow-HTTP-Header

If you want to help your clients: Send a proper Allow-Header (like defined in HTTP1.1 rfc2616):

Allow: GET, HEAD, PUT

This response is very helpful in OPTIONS/HEAD requests (if you want to know it before doing any non safe work on the URL) or when you send a 405 Method not Allowed response.

A bonus: The header might differ for a specific user, which may only be allowed to GET the resource, but not allowed to POST to it.

The next post in this series will be about avoiding custom HTTP methods and why you should stick to GET/HEAD/OPTIONS and POST.

In api, api-design, hal, hateoas, open source, rest by @ 29 May 2014

comments powered by Disqus

Recent Files

Advertisement

Recent Dev-Articles

Read recently

About

Blogroll