Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Responding to an idempotent HTTP POST request

Part of our RESTful API will allow users to register an item with a serial number. As the serial number is not globally unique it cannot be used as the identifier of the resource, so we'll use a POST to the parent resource which will generate an identifier, e.g.

POST /my/items

<item serial-number="ABCDEF" />

In the case where the item is not already registered, the HTTP semantics are well defined. We return a Location header, and the registered item as the entity body, e.g.

HTTP 201 Created
Location: /my/items/1234    

<item id="1234" serial-number="ABCDEF" />

However, in the case where the item is already registered, the API should be idempotent and return the previously registered item 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 actually came from, e.g.

HTTP 200 OK
Content-Location: /my/items/1234    

<item id="1234" serial-number="ABCDEF" />

Would this seem reasonable? I'm not entirely clear whether the Location or Content-Location is more suitable in the second case.

like image 947
Greg Beech Avatar asked Aug 11 '10 12:08

Greg Beech


People also ask

How do you handle idempotent?

Yet another approach is to use a separate client generated key to provide idempotency. In this way the client generates a key and adds it to the request using a custom header (e.g. Idempotency-Key). Now the server can persist the idempotency key and reject any further requests using the same key.

Can a post request be idempotent?

The POST method is not idempotent. To be idempotent, only the state of the server is considered. The response returned by each request may differ: for example, the first call of a DELETE will likely return a 200 , while successive ones will likely return a 404 .

What is idempotent HTTP request?

Idempotency means that multiple identical requests will have the same outcome. So it does not matter if a request is sent once or multiple times. The following HTTP methods are idempotent: GET, HEAD, OPTIONS, TRACE, PUT and DELETE.

How is Idempotency achieved in a request reply protocol?

Idempotency is achieved simply by allowing the client to supply the unique message identifier instead of assigning it within the Ably service on receipt of the message.


1 Answers

I had similar requirement recently. For idempotent operations PUT is the best way. You're right there is a mismatch between the external-id and the internal one. I solved it by creating a dedicated resource for the external id target:

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

Internally I resolve it as a CREATE in case I have no item for 'username' and 'ABCDEF' serial number or UPDATE in case I do.

In case it was a CREATE I return 201 for an UPDATE 200. Further more the returned payload contains both homegrown id and the external serial number like you suggested in your payload.

like image 121
manuel aldana Avatar answered Oct 09 '22 15:10

manuel aldana