How to achieve idempotency in POST method?

Saurav Singh
4 min readNov 13, 2018

--

Before I get into how to achieve idempotency in a POST request, I would like to explain what idempotent is, and the different idempotent REST methods available.

What is idempotent?

An operation is idempotent if it will produce the same results when executed over and over again.

Consider the following examples:

var a = 10;a++;

The first example is idempotent: no matter how many times we execute this statement, a will always be 10. The second example is not idempotent. Executing this n times will result in a different outcome.

An idempotent HTTP method is an HTTP method that can be called multiple times without different outcomes. It would not matter if the method is called only once, or n times over. The result should be the same.

List of idempotent Rest methods:

HTTP MethodOPTIONS        
GET
HEAD
PUT
DELETE

List of non-idempotent methods:

HTTP MethodPOST        
PATCH

Why every method is not idempotent, by default?
Post method always results in a server state change. If the POST method was idempotent, everything sent and accepted to or from the web server would already have to exist on the server in some form to respond with the same codes and value response. For that reason, POST cannot be idempotent.

How to achieve idempotency via POST method and why sometimes it’s very important?
Idempotency is important in building a fault-tolerant API.

Suppose a customer wants to make a payment. The client will then issue a POST request to the server in order to create the payment. Since POST is not an idempotent method, calling it multiple times can result in duplicate payments. What would happen if you sent out the POST request to the server, but you get a timeout? Is the resource actually updated? Does the timeout happen while sending the request to the server, or during the response to the client? Can the client safely retry again, or do we need to first figure out what has happened with the resource? By using idempotent methods, we do not have to answer this question, but we can safely resend the request until we actually get a response back from the server.

In order for the client to send the request again in case of network failure or no response from the server, we need to make our POST request idempotent.

The standard approach that you will notice is that of passing the unique Idempotency-key in every request made by the client.

Let me explain you by taking an example:

The endpoint shown in above image http://localhost:3000/transfer is a POST request for transferring an amount from one account to another. As you can see, we have passed 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 client, we can send the same request again and again without worrying about a duplicate request. Wait a minute. You must be thinking, “How will the server treat it as the same request again and again instead of a new one by simply adding the key?” now by just adding the key how the server will treat it as the same request again and again instead of new???

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.

Additional take ways:

  1. You can choose any storage for saving the Idempotency-key
  2. You can also set the expiry to your Idempotency-key to say 24hr

Conclusion:

After going through the above example, it’s clear that idempotent technique is important to build a fault-tolerant API; especially when you are dealing with payment-related stuff.

I hope this gives you a basic understanding of what idempotent is, and how to make POST method idempotent. Stay tuned for further updates on related topics.

Thank you for reading!

Feedback and thoughts are always welcome in the comments section.

--

--