What are idempotent methods in the HTTP? Probably you’ve been asked this question on the interview, or maybe you see it for the first time.
No doubts, it’s a concept which you should know in order to create good and fault-tolerant HTTP-based APIs.
In fact, idempotent methods in HTTP are not so complicated as their name may sound. So, let’s begin.
What are they?
When it comes to the official definition, let’s take a look at the HTTP/1.1 specs:
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.
So, in short: no matter how many requests you send, the outcome should be always the same.
But, at the same time, it’s important to think about the idempotency from the point of view of the resource `what will be the status of the resource?`, not from the point of view of the outcome – `what will happen? what will be the response?`.
So the actual response could differ, but the effect (resource status) will be always the same.
Idempotent methods in HTTP
According to the docs, the following methods are considered idempotent:
- OPTION
- GET
- HEAD
- PUT
- DELETE
In other words: only PUT, DELETE and safe methods are idempotent.
It makes sense, right? No matter how many times I send GET /items, the status of the resource won’t change and I should receive the same response.
Cool, that was easy. But what about DELETE? It does change things, doesn’t it?
Well, DELETE is rather used to remove a certain resource from the server and it usually happens when you send just the single one request. So is it idempotent or not?
Well, yes. It is. Take a look at this example:
- You send DELETE /items/1 – the resource (in this case it’s item) doesn’t exist
- You re-send DELETE /items/1 – the resource still doesn’t exist
- You re-send … etc. and the resource status is still the same
So, as you can see, the resource status doesn’t change.
The same thing with the PUT method. But here, instead of deleting a resource, you replace the entire document every time. So the status of the resource will always be the same.
What about POST and PATCH?
So, as you might already observe, POST and PATCH methods are not idempotent.
Why? Let’s think about it.
POST
Where do we usually use POST methods in our APIs?
Among others, according to docs, we use it for:
Creating a new resource that has yet to be identified by the origin server
So by definition, using POST brings the change of the server state.
So, the POST method is not idempotent because executing it more than once may bring unnecessary side-effects.
PATCH
The PATCH method has been introduced by RFC 5789 in 2010. It’s designed to allow us to modify an existing HTTP resource.
It isn’t idempotent by design but the good news is – we can make it idempotent. How is it possible?
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.(…)
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.
So, the PATCH can be idempotent, but it all depends on your implementation.
Why should we bother?
Idempotent methods are an important part of the fault-tolerant API.
The docs give us an interesting example of why do we distinguish idempotent methods at all and why should we bother:
For example, if a client sends a PUT request and the underlying connection is closed before any response is received,
then the client can establish a new connection and retry the idempotent request.It knows that repeating the request will have the same intended effect, even if the original request succeeded, though the response might differ.