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.