Search code examples
restspring-data-resthateoas

Should I use Location Header for the created resource if my API is already returning the self link as per HAL specification?


I was following some blogs and SO question and they recommend a Location header to be returned by the server with 201 created response. Spring-data-rest also returns the created resource location in the Location header.

But is it really needed??

Consider this POST request: curl -d '{..data}' -H "Content-Type: application/json" -X POST http://localhost:3000/persons
response:

{
  "name": "hero",
  "_links": {
    "self": {
      "href": "http://localhost:8081/persons/1"
    },
    "person": {
      "href": "http://localhost:8081/persons/1"
    }
  }
}

Since the response has the created resource's absolute location in self and person link, why would Location header be needed anymore?


Solution

  • If you want to be compliant with the HTTP spec (RFC 7231) you should return a Location header for a 201 Created response:

    If one or more resources has been created on the origin server as a result of successfully processing a POST request, the origin server SHOULD send a 201 (Created) response containing a Location header field that provides an identifier for the primary resource created (Section 7.1.2) and a representation that describes the status of the request while referring to the new resource(s).

    Certain client implementations will operate on such premises and if you violate the HTTP spec they might not be able to interact properly with your API.

    Furthermore, you have to distinguish between some media-type specific representation content and some general request-response metadata. The Location header belongs to the meta-data of the response. A client not understanding a certain representation format will still know that the server was able to store the content at the given URI.

    Think of a scenario where an arbitrary client sends data to the server and the server stores that data in a representation format not understood by the client (which the server is allowed to), how should the client determine the location of the data or retrieve the data in future? It can't process the response due to a lack of knowledge about the representation format returned and by omitting such information from the headers the client is blind and wont be able to request this data again easily. By introducing a representation-neutral hint that every well-behaved implementation should follow a client can make sense of that at least. It might still not be able to process the response payload correctly, but it knows the data is available at that respective location.

    Client and server should negotiate about the actual media-type to exchange messages for in order to increase interoperability. A media-type describes therefore the syntax and semantics of the elements that may appear in a message exchanged as well as the ruleset to process the request, i.e. that certain elements may only appear in certain conditions. Just exchanging application/json doesn't provide a client with much information on how the data should be processed other that certain key-value pairs are contained in a curly-brace'esque notation. While hal+json adds semantics for URIs, it doesn't specify the key to be used for returning a created resource, as this is already covered by the HTTP spec already.

    In regards to REST, you may take the Web as an example on how to design the interaction flow between client and server. The premise here should always be that a server teaches clients on what they can do next through form-like representation formats and provided links. The ultimate goal of a REST architecture is the decoupling of clients from servers which allows the latter to evolve freely in future without breaking clients. This, however, requires careful design as it is to easy to introduce an unintended coupling.