Why is the HTTP location header only set for POST requests/201 (Created) responses?
Asked Answered
A

2

5

Ignoring 3xx responses for a moment, I wonder why the HTTP location header is only used in conjunction with POST requests/201 (Created) responses.

From the RFC 2616 spec:

For 201 (Created) responses, the Location is that of the new resource which was created by the request.

This is a widely supported behavior, but why shouldn't it be used with other HTTP methods? Take the JSON API spec as an example:

It defines a self referencing link for the current resource inside the JSON payload (not uncommon for RESTful APIs). This link is included in every payload. The spec says that you MUST include an HTTP location header, if you create a new document via POST and that the value is the same as the self referencing link in the payload, but this is ONLY needed for POST. Why bother with a custom format for a self referencing link, if you could just use the HTTP location header?

Note: This isn't specific to JSON API. It's the same for HAL, JSON Hyper-Schema or other standards.

Note 2: It isn't even specific to the HTTP location header as it is the same with the HTTP link header. As you can see the JSON API, HAL and JSON Hyper-Schema not only define conventions for self referencing links, but also to express information about related resources or possible actions for a resource. But it seems that they all could just use the HTTP link header. (They could even put the self referencing link into the HTTP link header, if they don't want to use the HTTP location header.)

I don't want to rant, it just seems to be some sort of "reinventing the wheel". It also seems to be very limiting: if you would just use HTTP location/link header, it doesn't matter if you ask for JSON, XML or whatever in your HTTP accept header and you would get useful meta-information about your resource on a HEAD request, which wouldn't contain the links if you would use JSON API, HAL or JSON Hyper-Schema.

Asylum answered 4/6, 2014 at 13:52 Comment(0)
S
8

The semantics of the Location header isn't that of a self-referencing link, but of a link the user-agent should follow in order to complete the request. That makes sense in redirects, and when you create a new resource that will be in a new location you should go to. If your request is already completed, meaning you already have a full representation of the resource you wanted, it doesn't make sense to return a Location.

The Link header may be considered semantically equivalent to an hypertext Link, but it should be used to reference metadata related to the given resource when the media-type is not hypermedia-aware, so it doesn't replace the functionality of a link to related resources in a RESTful API.

The need for a custom link format in the resource representation is inherent to the need to decouple the resource from the underlying implementation and protocol. REST is not coupled to HTTP, and any protocol for which there's a valid URI scheme can be used. If you decided to use the Link header for all links, you're coupling to HTTP.

Let's say you present an FTP link for clients to follow. Where would be the Link in that case?

Spinous answered 4/6, 2014 at 16:31 Comment(9)
"REST is not coupled to HTTP, and any protocol for which there's a valid URI scheme can be used. [...] If you decided to use the Link header for all links, you're coupling to HTTP." I think this point is the one, which is the most coherent for me.Asylum
I'm sorry, after thinking about it again I think I don't get it... "The Link header should be used to reference metadata related to the given resource." That sounds to be exactly the same as "functionality of a link to related resources in a RESTful API"? "REST is not coupled to HTTP"... Maybe. But if this would be a problem, wouldn't I need to expose my HTTP methods in my payload, too? E.g. /users/123/delete or /users/123/put? My DELETE and PUT depends on HTTP... why shouldn't my links?Asylum
But as another counter-argument: Should I treat my JSON documents for machines the same as my HTML documents for humans...? I wouldn't ask, if I should move the links and buttons from my HTML into the HTTP header...Asylum
Yes, in that sense you may say the link header is semantically equivalent to the links in the payload, and some people defend implementing HATEOAS with the Link header alone. I think it should be reserved only for media-types that are not hypermedia-aware. Just think that REST is an architectural style based on the successful design decisions made for the web itself. A REST API should be navigable and discoverable in the same way a website is. Do you usually check for links in your HTTP headers when you're browsing a webpage?Spinous
If you're not treating your JSON documents in the same way as your HTML for humans, meaning they're not hypermedia-aware, then you're not using REST. You should use the Link header when you need to provide links for a media-type that's not hypermedia-aware. For instance, you want to reference the author of an image. You can't embed a link in the image itself. Recommended reading: roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-drivenSpinous
Regarding methods in your hypermedia documents, this discussion popped up recently. You might want to check that group too. groups.google.com/forum/#!topic/api-craft/v0GNu7ksO3sSpinous
Thank you very much for your effort. I'll look into your last link. (I know the article from the first link, but it is very theoretical. I says to "do" hypertext, but not exactly "how".)Asylum
There's no mystery about the how: it's how any website does. It's usually not so obvious because most APIs use a format like JSON, with no native syntax for hyperlinks. Check hal+json, it should give you ideas. stateless.co/hal_specification.htmlSpinous
I think it "is" a little mystery. If it would be obvious, we wouldn't have so much specs doing it all differently :) hal+json is just "one" way to do it. Thanks again for your reply.Asylum
F
6

The semantic of the Location header depends on the status code. For 201, it links to the newly created resource, but in 3xx requests it can have multiple (although similiar) meanings. I think that is why it is generally avoided for other usages.

The alternative is the Content-Location header, which always has a consistent meaning. It tells the client the canonical URL the resource it requested. It is purely informative (in contrast to the Location, which is expected to be processed by the client).

So, the Content-Location header seems to closer resemble a self-referencing link. However, the Content-Location also has no defined behavior for PUT and POST. It also seems to be quite rarely used.

This blogs post Location vs Content-Location is a nice comparison. Here is a quote:

Finally, neither header is meant for general-purpose linking.

In sum, requiring a standardized, self link in the body seems to be good idea. It avoids a lot of confusion on the client side.

Forgiveness answered 4/6, 2014 at 22:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.