Response to an idempotent HTTP POST request

Part of our RESTful API will allow users to register an item with a serial number. Since the serial number is not globally unique, it cannot be used as a resource identifier, so we will use POST for the parent resource that will generate the identifier, for example.

POST /my/items <item serial-number="ABCDEF" /> 

In the case when the element is not yet registered, the HTTP semantics are defined correctly. We return the Location header and the registered item as the body of the object, for example.

 HTTP 201 Created Location: /my/items/1234 <item id="1234" serial-number="ABCDEF" /> 

However, when an element is already registered, the API must be idempotent and return the previously registered element without creating a new one. My best guess is that it should then return a 200 OK status code and use the Content-Location header to indicate where the item came from, e.g.

 HTTP 200 OK Content-Location: /my/items/1234 <item id="1234" serial-number="ABCDEF" /> 

It would seem reasonable? I don’t quite understand if Location or Content-Location is suitable in the second case.

+6
source share
2 answers

I have had a similar requirement recently. For idempotent operations, PUT is the best way. You are right, there is a mismatch between the external and the internal. I solved this by creating a dedicated resource for the purpose of an external identifier:

 PUT /api-user/{username}/items/{serialNumber} 

Internally, I enable it as CREATE if I don't have an element for the 'username' and 'ABCDEF' of the serial number or UPDATE in case I do this.

In case it is CREATE, I return 201 for UPDATE 200. In addition, the returned payload contains both the homegrown identifier and the external serial number, as you indicated in your payload.

+7
source

Here's an interesting discussion about using two headers. He claims that Content-Location is not specific to PUT or POST, so location is probably the best option in your case. This, of course, is not a clear cut, which is better, though.

All in all, I think your approach makes sense, though.

+1
source

All Articles