Is REST DELETE really idempotent?
Asked Answered
T

8

228

DELETE is supposed to be idempotent.

If I DELETE http://example.com/account/123 it's going to delete the account.

If I do it again would I expect a 404, since the account no longer exists? What if I attempt to DELETE an account that has never existed?

Triviality answered 3/11, 2010 at 14:55 Comment(1)
In addition to the answers, I'd suggest not to focus too much on the idempotent characteristic in general: it doesn't say anything about commutativity and concurrent requests. For example N+1 of the same "R1" PUT request should have the same effect, but you don't know if another client made a different PUT/DELETE "R2" request in between yours, so while nR1=R1 and mR2=R2, something where you get interleaved "R1" and "R2" requests won't necessarily "look" idempotent if you only take the perspective of a single client.Nietzsche
P
254

Idempotence refers to the state of the system after the request has completed


In all cases (apart from the error issues - see below), the account no longer exists.

From here

"Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request. The methods GET, HEAD, PUT and DELETE share this property. Also, the methods OPTIONS and TRACE SHOULD NOT have side effects, and so are inherently idempotent. "


The key bit there is the side-effects of N > 0 identical requests is the same as for a single request.

You would be correct to expect that the status code would be different but this does not affect the core concept of idempotency - you can send the request more than once without additional changes to the state of the server.

Pedicular answered 3/11, 2010 at 15:6 Comment(8)
Side-effects !== server stateLandis
@Landis There is a debate on what this "side-effect" really is. It may be "server state" or it may be response sent to client.leedavis81.github.io/is-a-http-delete-requests-idempotentFlameout
Here's an argument that 404 on a second DELETE may actually change the state of the server: https://mcmap.net/q/45868/-status-code-when-deleting-a-resource-using-http-delete-for-the-second-timeWeep
@PauloMerson Thanks, personally I don't think it matters whether the second return is 404 or 200, the state of the server hasn't changed so I'm happy with that.Pedicular
Define "state of the server"Specialism
@Specialism - think of it as the persistent state. No matter how many times you delete the resource, and regardless of the http result code, the resource is gone from the persistent state. Does that help?Pedicular
Thanks @ChrisMcCauley. Can you give a counterexample of an idempotent method?Specialism
@Specialism If you call "add item to cart" n times with no changes and end up with n of the same item in the cart, then that's not idempotent...each time you make the same call the state changes because there's another item added to the cart. (In the bad old days, if you accidentally double clicked on the "purchase" button it would place the same order twice! Now people add a token to make purchase idempotent, so if your mouse sticks or the first try fails you can safely try again.)Griz
N
60

Idempotent is about the effect of the request, not about the response code that you get.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.2 says:

Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

While you may get a different response code, the effect of sending N+1 DELETE requests to the same resource can be considered to be the same.

Nietzsche answered 3/11, 2010 at 15:5 Comment(0)
I
23

Quoted from my answer to another question:

Historically, RFC 2616, published at 1999, was the most-referenced HTTP 1.1 specs. Unfortunately its description on idempotency was vague, that leaves room for all these debates. But that specs has been superseded by RFC 7231. Quoted from RFC 7231, section 4.2.2 Idempotent Methods, emphasis mine:

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.

So, it is written in the specs, idempotency is all about the effect on the server. The first DELETE returning a 204 and then subsequent DELETE returning 404, such different status code does NOT make the DELETE non-idempotent. Using this argument to justify a subsequent 204 return, is simply irrelevant.

OK so it is not about idempotency. But then a follow-up question may be, what if we still choose to use 204 in subsequent DELETE? Is it OK?

Good question. The motivation is understandable: to allow the client to still reach its intended outcome, without worrying about error handling. I would say, returning 204 in subsequent DELETE, is a largely harmless server-side "white lie", which the client-side won't immediately tell a difference. That's why there are people doing that in the wild and it still works. Just keep in mind that, such lie can be considered semantically weird, because "GET /non-exist" returns 404 but "DELETE /non-exist" gives 204, at that point the client would figure out your service does not fully comply with section 6.5.4 404 Not Found.

But then, the intended way hinted at by RFC 7231, i.e. returning 404 on a subsequent DELETE, shouldn't be an issue in the first place. Many more developers choose to do that. That is presumably because, any client which implements HTTP DELETE (or any HTTP method, for that matter), would not blindly assume the result would always be successful 2xx. And then, once the developer starts to consider the error handling, 404 Not Found would be one of the first errors that comes to mind. At that point, he/she would hopefully draw a conclusion that it is semantically safe for an HTTP DELETE operation to ignore a 404 error. Problem solved.

Interplanetary answered 15/3, 2020 at 16:58 Comment(3)
This is the clearest answer: 204, then 404's and does not imply non-idempotent because it is about server state not what gets returned to the userHype
great follow up question :) "such lie can be considered semantically weird, because "GET /non-exist" returns 404 but "DELETE /non-exist" gives 204" makes a lot of sense.Molybdenite
Interestingly RFC9110 does not mention 404 as a response to a DELETE method. But the document does state 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. Indeed intended effect and response are unrelated.Reverberate
T
20

The important distinction is that idempotent refers to side-effects, not all-effects or responses. If you do a DELETE http://example.com/account/123 then the effect is that account 123 is now deleted from the server. That is the one and only effect, the one and only change to the state of the server. Now lets say you do the same DELETE http://example.com/account/123 request again, the server will respond differently, but its state is the same.

Its not like the DELETE request decided to change the server state in a different way because the account was missing, such as removing another account, or leaving an error log. Nay, you could call the same DELETE request a million times and you can be sure that the server is in the same state as it was the first time you called it.

Tachometer answered 9/5, 2017 at 20:21 Comment(0)
M
14

Yes. Regardless of the response code.

From latest RFC for HTTP 1.1 (emphasis mine):

Idempotent methods are distinguished because the request can be repeated automatically if a communication failure occurs before the client is able to read the server's response. 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.

It explicitly says that the response might differ. More importantly, it points out the reason of the concept: if an action is idempotent, the client can repeat the action when it encounters any error, and knows that it won't crash anything by doing so; if not, the client will have to make an additional query (possibly GET) to see whether the previous one is effective, before it safely repeat the action. As long as the server can make such guarantee, the action is idempotent. Quote from another comment:

Computing idempotence is about the robustness of a system. Since things can fail (e.g. network outage), when a failure is detected, how do you recover? The easiest recovery is to just do it again, but that only works if doing it again is idempotent. E.g. discard(x) is idempotent, but pop() is not. It's all about error recovery.

Mishnah answered 19/12, 2017 at 21:18 Comment(1)
This answer makes the most sense, this should be the accepted one.Metz
K
11

From the HTTP RFC:

Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

Note that's "side effects", not "response".

Krakow answered 3/11, 2010 at 15:9 Comment(0)
G
7

Suppose we have to manage football teams represented by id, name and city.

{
    id: "1",
    name: "manchester united",
    city : "manchester "
}

Saying that DELETE is idempotent means that if you invoke DELETE /team/1 several times the state of the system stays unchanged (in fact the first call DELETE /team/1 deletes the team). In other words, DELETE is idempotent because duplicated calls leave the state of system unchanged.

In the same way we can say that PUT is also idempotent. Imagine you do this PUT more than once:

PUT /team/1
{
    id: "1",
    name: "liverpool",
    city : "liverpool"
}

Duplicated calls of such PUT requests always have the same effect (the team 1 will be liverpool).

It is obvious that GET requests are idempotent too.

Gamone answered 3/8, 2020 at 0:43 Comment(0)
A
1

I think the same thing, 404 - Account doesn't exist.

You could argue 400 - Bad Request. But in the sense of REST the object you requested to perform an action on doesn't exist. That translates to 404.

Accountant answered 3/11, 2010 at 14:59 Comment(4)
To generate a 400 you would have to know that the object used to exist, which is very un-restful.Drivel
@annakata, 400 is not even for resources that used to exist (perhaps you have 410/Gone in mind), it's for bad requests "The request could not be understood by the server due to malformed syntax."Nietzsche
@Nietzsche - I'm aware of what it means, the OP cited it.Drivel
I think 200 would be fine. You want the state of the server to be that the account is gone. Does it matter which request actually made it go away? It's still gone on the second request, server state hasn't changed.Skyla

© 2022 - 2024 — McMap. All rights reserved.