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?
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.
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.
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".
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.
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.
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.