HTTP POST response Location header when creating multiple resources

metacubed picture metacubed · Mar 17, 2015 · Viewed 10.8k times · Source

The HTTP/1.1 standard states that if a POST operation results in the creation of a resource, then the response should include a Location header with the address of the new resource.

If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header (see section 14.30).

and in section 14.30,

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

Now suppose that my API allows batch creation of resources by POSTing an array to the collection resource URL. For example:

POST /books
[
    {
        "name": "The Colour of Magic",
        "published": "1983"
    },
    {
        "name": "The Light Fantastic",
        "published": "1986"
    }
]

Since two \book\{bookId} resources have been created, what should be the value of the Location header in this case?

The question Http post response after multiple new resource creation? is similar, but it asks about the response entity, not the headers (and is unanswered).

Answer

MikeSchinkel picture MikeSchinkel · Jun 20, 2016

I know this answer is late to the party but I believe the best solution is to create a new Batches resource with a uuid identifier that would return the list of Book URLs that were added using a URL like this:

http://api.example.com/batches/{uuid}

e.g.

http://api.example.com/batches/2b9b251f71a4b2901d66e04725bc0c9cb5843c74

Then your POST or PUT can return the above URL on it's Location: {url} header and a 201 - Created status code.

If you then GET that URL it would then the list of URLs created in that batch as well as any other info about the batch such as its uuid and the time/date it was created.

{
  "uuid": "2b9b251f71a4b2901d66e04725bc0c9cb5843c74",
  "datetime": "2005-08-15T15:52:01+00:00",
  "books": [
    "http://api.example.com/books/the-colour-of-magic",
    "http://api.example.com/books/the-light-fantastic"
  ]
}

Those resources could then have a TTL of an hour or a month, whatever you choose. Of they could live forever if you want; whatever your use-case requires.