In the context of REST APIs, when making multiple identical requests has the same effect as making a single request – then that REST API is called idempotent.
When you design REST APIs, you must realize that API consumers can make mistakes. Users can write client code in such a way that there can be duplicate requests coming to the API.
These duplicate requests may be unintentional as well as intentional some time (e.g. due to timeout or network issues). You have to design fault-tolerant APIs in such a way that duplicate requests do not leave the system unstable.
Idempotence essentially means that the result of a successfully performed request is independent of the number of times it is executed. For example, in arithmetic, adding zero to a number is an idempotent operation.
Idempotency with HTTP Methods
If you follow REST principles in designing API, you will have automatically idempotent REST APIs for GET, PUT, DELETE, HEAD, OPTIONS and TRACE HTTP methods. Only POST
APIs will not be idempotent.
POST
is NOT idempotent.GET
,PUT
,DELETE
,HEAD
,OPTIONS
andTRACE
are idempotent.
Let’s analyze how the above HTTP methods end up being idempotent – and why POST is not.
HTTP POST
Generally – not necessarily – POST
APIs are used to create a new resource on server. So when you invoke the same POST request N times, you will have N new resources on the server. So, POST is not idempotent.
HTTP GET, HEAD, OPTIONS and TRACE
GET
, HEAD
, OPTIONS
and TRACE
methods NEVER change the resource state on server. They are purely for retrieving the resource representation or meta data at that point of time. So invoking multiple requests will not have any write operation on server, so GET, HEAD, OPTIONS and TRACE are idempotent.
HTTP PUT
Generally – not necessarily – PUT
APIs are used to update the resource state. If you invoke a PUT
API N times, the very first request will update the resource; then rest N-1 requests will just overwrite the same resource state again and again – effectively not changing anything. Hence, PUT is idempotent.
HTTP DELETE
When you invoke N similar DELETE
requests, first request will delete the resource and response will be 200 (OK)
or 204 (No Content)
. Other N-1 requests will return 404 (Not Found)
. Clearly, the response is different from first request, but there is no change of state for any resource on server side because original resource is already deleted. So, DELETE is idempotent.
Please keep in mind if some systems may have DELETE APIs like this:
DELETE /item/last
In the above case, calling operation N times will delete N resources – hence DELETE
is not idempotent in this case. In this case, a good suggestion might be to change the above API to POST – because POST is not idempotent.
POST /item/last
Now, this is closer to HTTP spec – hence more REST compliant.
References:
Ju says
PATCH is missing. It’s ike POST not idempotent since it’s usually used to partially update a resource (for example just sending and setting the first name of a user profile, ignoring the state of the remaining data).
AFAIK PUT can also create a new entity (but always the same, so calling it twice wouldn’t create two entities – basically you’re providing also the ID of the element to be created and if it already exists it’s being overwritten, but it doesn’t have to exist when using PUT the first time). Of course this depends on the implementation. But it would be valid.
Admin says
Thanks for sharing your thoughts. It helps.
Pavan says
When we send a POST request, it will create a new resource. Now if we resend identical POST request N times, conflict error would be returned as an identical record already exists. So, in this case will POST be idempotent (like the DELETE case you mentioned) as the resource on server remains same?
Hua Liang says
I think you are more like a business/implementation side of question while this post is merely providing concept/theory of REST idempotence in general.
John says
In a POST, the server determines the new ID, not the client, so that would be an improper implementation. PUT is appropriate for creation when the client is allowed to determine the new resource ID, so that scenario should use a PUT, which would be idempotent.
Andrzej Pienczykowski says
It is a good practice to have a candidate keys that by definition are also unique. That would prevent creating duplicate resources. It is obviously not possible for all types of resources.
Orijit says
Resending identical POST requests N times will create N resources, each with a new ID. In the case an ID is involved, PUT would update the document with the same ID N number of times and produce same result.
Tony Wallace says
Wrong. A put is NOT the same as a create command in a database. It is more like writing out a file out of a text editor. If it does not exist, it creates the resource (return 201), it it does exist it updates it (return 200).
Venkatesan Natarajan says
You can achieve idempotency in POST method for building a fault-tolerant API.
The standard approach that you will notice is that of passing the unique Idempotency-key in every request made by the client. we can pass an Idempotency-key with a unique value which is in the UUIDV4 format in the headers. Now in case of network failure or no response from the server , client can send the same request again and again without worrying about a duplicate request.
Let me explain the server side implementation:
On the server side, we have created a middleware. This middleware will check each of the requests coming into the application, and check if the Idempotency-key is present in the headers.
If the Idempotency-key is present in the request, we will query the database, and check if there’s a record corresponding to that Idempotency-key. If there is, the middleware will stop any further execution in the middleware layer itself, and will immediately respond with the saved data as a response.
Otherwise, it will continue to the application layer and will create a new record in the database with the Idempotency-key and the generated response, and finally return the same response to the client.
Therefore, any request with the same Idempotency-key already seen earlier by the server will not be treated as new and server will return the cached response.
Mariot says
Shouldn’t it be “POST /item/last/delete” ?
Yves De Muyter says
Can you explain to me what resource is /item/last/delete ? It’s an URL so a resource, but I’m not sure what a “delete” resource is exactly…
Admin says
Almost 2 yrs now. I have no recall why nodded to that.