DELETE应该是幂等的。

如果我删除http://example.com/account/123,它将删除帐户。

如果我再次这样做,我将期望404,因为帐户不再存在?如果我试图删除一个从未存在过的帐户怎么办?


当前回答

重要的区别是,幂等指的是副作用,而不是所有的效应或反应。如果执行DELETE http://example.com/account/123,则结果是帐户123现在已从服务器上删除。这是唯一的效果,服务器状态的唯一变化。现在假设您再次执行相同的DELETE http://example.com/account/123请求,服务器将以不同的方式响应,但其状态是相同的。

这并不像DELETE请求决定以不同的方式改变服务器状态,因为帐户丢失了,比如删除另一个帐户,或留下一个错误日志。不,您可以调用相同的DELETE请求一百万次,并且可以确保服务器处于与您第一次调用它时相同的状态。

其他回答

来自HTTP RFC:

方法还可以具有“幂等性”属性,即(除了错误或过期问题外)N > 0个相同请求的副作用与单个请求相同。

注意这里是“side effects”,而不是“response”。

幂等性指的是请求完成后系统的状态

在所有情况下(除了错误问题-见下文),该帐户不再存在。

从这里

方法也可以具有的属性 “幂等性”(除了 错误或过期问题) 副作用N > 0相同 请求与单个请求相同 请求。方法GET, HEAD, PUT 和DELETE共享此属性。同时, 方法OPTIONS和TRACE应该 没有副作用,所以 本质上是等幂的。”

关键是N个>个相同请求的副作用与单个请求相同。

您期望状态码会有所不同是正确的,但这并不影响等幂的核心概念——您可以多次发送请求,而无需对服务器的状态进行额外更改。

是的。不管响应代码是什么。

来自HTTP 1.1的最新RFC:

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:

计算幂等关系到系统的鲁棒性。由于事情可能会失败(例如网络中断),当检测到故障时,如何恢复?最简单的方法就是再做一遍,但只有在幂等的情况下才有效。例如,discard(x)是幂等的,但pop()不是。这都是关于错误恢复的。

假设我们必须管理以id、名称和城市表示的足球队。

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

说DELETE是幂等的意味着如果多次调用DELETE /team/1,系统的状态保持不变(实际上第一次调用DELETE /team/1会删除团队)。换句话说,DELETE是幂等的,因为重复调用保持系统状态不变。

同样地,我们可以说PUT也是等幂的。 假设你做了不止一次PUT:

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

这种PUT请求的重复调用总是具有相同的效果(球队1将是利物浦)。

很明显,GET请求也是幂等的。

幂等性是关于请求的效果,而不是你得到的响应代码。

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

方法也可以具有的属性 “幂等性”(除了 错误或过期问题) 副作用N > 0相同 请求与单个请求相同 请求。

虽然您可能会得到不同的响应代码,但可以认为向同一资源发送N+1个DELETE请求的效果是相同的。