A common interview question asked by interviwers regarding API testing is – Difference between PUT and POST.

One point that gets raised in this is that PUT is idempotent, while POST isn’t.

But what is idempotence? When we say an operation is idempotent, what does it mean?
Let’s see.

In mathematics or also in computing, an idempotent operation is the one which has no additional effect , if it is called more than once with the same input parameters.

A perfect example can be

  • Add a number with 0 – no matter how many times you add it- the end impact is going to be same.
  • Multiply a number with 0 – it will be 0 no matter how many times you multiply.

The mathematical definition of an idempotent operation is – an idempotent operation is one where f(f(x)) = f(x).

A good example is the absolute value of any number – which can be found using abs() method – no matter how many times you do it – like abs(abs(x)) it is going to be equal to abs(x).

In the content of RESTful web services, when we talk about the concept of idempotency, we generally talk about in the terms of the HTTP methods. REST recoganizes a web application into “resources” (like a Twitter user, or a Flickr image) and then uses the HTTP verbs of POST, PUT, GET, and DELETE to create, update, read, and delete those resources. And so, Idempotency is a property of HTTP methods.

A request method in REST is considered as idempotent , if the end impact on the server of multiple identical requests with that method, would yield the same impact, as that of a single request method.

Now the word – end impact on the server is very important. REST emphasises that the idempotency is about the the impact or the effect produced on the state of the resource on the server and not on the response code or the response status recieved.

This principle stated above can be best illustrated by the use of the DELETE http method. DELETE is considered as an idempotent method in REST.
Consider a scenario where a client wants to DELETE a resource on the server. The client issues a DELETE request, and the request in turn deletes the resource from the server and would in turn return a success (200) or may be a 204 (No Content) based on how the configuration has been done.

If you issue the request to delete the resource again and again with the same id, then the server may respond with a Not-Found (404) – however the effect would be the same as that of the first request. It would only try to delete the same resource again and again.

The RFC 7231 defines both the safe methods and idempotent methods in a concise way – in section 4.2.1 and 4.2.2 respectively

Safe Methods

Request methods are considered “safe” if their defined semantics are essentially read-only; i.e., the client does not request, and does not expect, any state change on the origin server as a result of applying a safe method to a target resource. Likewise, reasonable use of a safe method is not expected to cause any harm, loss of property, or unusual burden on the origin server.

Idempotent Methods

A request method is considered “idempotent” if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request. Of the request methods defined by this specification, PUT, DELETE, and safe request methods are idempotent.

Now considering the HTTP verbs, we can easily see that why a GET call is an idempotent call – unless there is a state change in between two consecutive GET calls, the response for this

GET  /resource/123

would be same in the first time as it will be in the Nth time.

Same goes for

PUT   /resource/123

However, if you fire a POST request , N times, it will create new records N times, and the desired state of the resource on server would not be the same as that of GET call. And that is why POST is not classified as an idempotent method.

So summarising the HTTP methods –

What about PATCH?

In the image above, we have seen which HTTP methods are marked safe and idempotent. One method that seems missing is PATCH. So what about it.

As per the RFC 5789, PATCH is neither defined safe nor idempotent. – directly quoting from the spec –

PATCH is neither safe nor idempotent as defined by [RFC2616], Section 9.1.

However, this doesn’t mean that it cannot be idempotent at all – just like it is defined that POST can be cacheable, but it is not implemented.

A PATCH request can be issued in such a way as to be idempotent, which also helps prevent bad outcomes from collisions between two PATCH requests on the same resource in a similar time frame. Collisions from multiple PATCH requests may be more dangerous than PUT collisions because some patch formats need to operate from a known base-point or else they will corrupt the resource. Clients using this kind of patch application SHOULD use a conditional request such that the request will fail if the resource has been updated since the client last accessed the resource. For example, the client can use a strong ETag [RFC2616] in an If-Match header on the PATCH request.

When to use idempotence

Idempotence is a safe practice for DevOps teams when developing applications. Idempotence ensures a safe, quality experience for both users and software teams. No one has to go in afterwards and clean up a mess.

For example, idempotence is the design standard for Ansible, a DevOps tool for system administrators to manage their servers. Ansible can automate the server setup process, consistently create the same servers, and automatically deploy them. There is a lot of orchestration that occurs in automating this process—and it is idempotent behaviors that ensure only one directory gets created on a server, and only an exact number of servers get created.

The idempotence function can be used in a variety of ways. Engineers want the destination to be the same, but the route that an orchestrator wishes to take can be different. If one function is called and the route it takes fails, another route can be tried. If one route lags, and a new one is fired, then, if both tasks make it to the endpoint, the result at the destination can still be the same.

Idempotent behavior is ever more crucial in cloud computing and edge devices. When multiple accounts can be logged in at once, accessed from different locations and different devices, updated from multiple user accounts, and data sent from one place to another, idempotent design helps manage the application’s state more efficiently and without error.

In the end, I hope I was able to make my points on what idempotent is and how it is implemented in the various HTTP methods. I was inspired by a post by Omprakash Chavan, who has a great course of API testing.