DELETE应该是幂等的。
如果我删除http://example.com/account/123,则会删除该帐户。
如果我再次这样做,我会期待404,因为该帐户不再存在?如果我尝试删除从未存在的帐户该怎么办?
答案 0 :(得分:167)
在所有情况下(除了错误问题 - 见下文),帐户不再存在。
来自here
“方法也可以具有的属性 “幂等”在那里(除了 错误或过期问题) N的副作用> 0相同 请求与单个请求相同 请求。方法GET,HEAD,PUT 和DELETE共享此属性。也, OPTIONS和TRACE应该是方法 没有副作用,等等 本质上是幂等的。 “
关键位是N的副作用。 0个相同的请求与单个请求相同。
您希望状态代码不同,但这不会影响幂等性的核心概念 - 您可以多次发送请求而无需对服务器状态进行其他更改。
答案 1 :(得分:39)
幂等是关于请求的效果,而不是关于您获得的响应代码。
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.2说:
方法也可以具有的属性 “幂等”在那里(除了 错误或到期问题) N的副作用> 0相同 请求与单个请求相同 请求。
虽然您可能会收到不同的响应代码,但可以认为向同一资源发送N + 1 DELETE请求的效果是相同的。
答案 2 :(得分:7)
答案 3 :(得分:5)
引自我的another answer here:
从历史上看,1999年发布的RFC 2616是引用最多的HTTP 1.1规范。不幸的是,its description on idempotency was vague为所有这些辩论留出了空间。但是该规范已被RFC 7231取代。引自RFC 7231, section 4.2.2 Idempotent Methods,重点是我的:
如果预期的效果为ON,则请求方法被视为“幂等” 使用该方法的多个相同请求的服务器是 与单个此类请求的效果相同。在请求方法中 由该规范,PUT,删除和安全的请求方法定义 是幂等的。
所以,它写在规范中,幂等性全是关于对服务器的影响。第一个DELETE返回204,然后后续的DELETE返回404,这样的不同状态代码不会使DELETE成为非等幂的。使用此参数来证明随后的204返回是正确的。
好,所以这与幂等无关。但是接下来的问题可能是,如果我们仍然选择在后续的DELETE中使用204,该怎么办?可以吗?
好问题。动机是可以理解的:允许客户仍然达到预期的结果,而不必担心错误处理。我要说的是,在后续的DELETE中返回204,这在很大程度上是服务器端的“善意谎言”,客户端不会立即告诉别人。这就是为什么有人在野外这样做并且仍然有效的原因。请记住,这种谎言在语义上可能是奇怪的,因为“ GET /不存在”返回404,而“删除/不存在”给出204,此时客户会发现您的服务不完全符合section 6.5.4 404 Not Found。
但是,RFC 7231所暗示的预期方式,即在随后的DELETE上返回404,首先不应该成为问题。更多的开发人员选择这样做。大概是因为,任何实现HTTP DELETE(或任何HTTP方法)的客户端都不会盲目地假设结果将始终是成功的2xx。然后,一旦开发人员开始考虑错误处理,“ 404 Not Found”将是第一个想到的错误之一。到那时,他/她希望得出一个结论,即HTTP DELETE操作忽略404错误在语义上是安全的。问题解决了。
答案 4 :(得分:3)
是。无论响应代码如何。
来自latest RFC for HTTP 1.1(强调我的):
因为请求可以区分幂等方法 如果在通信失败之前发生,则自动重复 客户端能够读取服务器的响应。例如,如果是 客户端发送PUT请求,底层连接关闭 在收到任何响应之前,客户端可以建立新的响应 连接并重试幂等请求。它知道重复 该请求将具有相同的预期效果,即使是原始的 请求成功,尽管响应可能不同。
它明确表示响应可能不同。更重要的是,它指出了这个概念的原因:如果一个动作是幂等的,那么客户端可以在遇到任何错误时重复动作,并且知道它不会因为这样做而崩溃。如果没有,客户端必须在安全地重复操作之前进行额外的查询(可能GET
)以查看前一个查询是否有效。只要服务器能够做出这样的保证,该动作就是幂等的。引自another comment:
计算幂等性是关于系统的健壮性。由于事情可能会失败(例如网络中断),当检测到故障时,您如何恢复?最简单的恢复是再次执行,但只有再次执行才是幂等的。例如。
discard(x)
是幂等的,但pop()
不是。这完全是关于错误恢复的。
答案 5 :(得分:2)
我认为同样的事情,404 - 帐户不存在。
你可以争辩400 - 不良请求。但就REST而言,您请求执行操作的对象不存在。这转化为404.
答案 6 :(得分:1)
假设我们必须管理以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请求也是幂等的。