REST DELETE真的是幂等的吗?

DELETE应该是幂等的。

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

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

47885 次浏览

我也是这么想的,404 -账户不存在。

你可以争辩400 -坏请求。但是在REST的意义上,您请求执行操作的对象并不存在。这意味着404。

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

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

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

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

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

< br >

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

在这里

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

< p > < br > 这里的关键位是N > 0个相同请求的副作用与单个请求相同。

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

HTTP RFC:

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

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

重要的区别是幂等指的是副作用,而不是所有-effects或responses。如果你执行DELETE http://example.com/account/123,那么结果就是账号123现在从服务器上删除了。这是唯一的效果,唯一的改变到服务器的状态。现在让我们假设你再次执行相同的DELETE http://example.com/account/123请求,服务器将以不同的方式响应,但其状态是相同的。

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

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

来自HTTP 1.1的最新RFC(强调我的):

幂等方法是不同的,因为请求可以是 重复,如果通信失败之前发生 客户端能够读取服务器的响应。例如,如果a 客户端发送PUT请求并关闭底层连接 在收到任何响应之前,客户机可以建立一个新的 连接并重试幂等请求。它知道重复 请求会有相同的预期效果,即使是原来的 尽管人们的反应可能有所不同。

.请求成功

它明确地说,反应可能会有所不同。更重要的是,它指出了这个概念的原因:如果一个动作是幂等的,客户端可以在遇到任何错误时重复这个动作,并且知道这样做不会导致任何崩溃;如果不是,客户端将不得不进行额外的查询(可能是GET),以查看前一个查询是否有效,然后才能安全地重复该操作。只要服务器能做出这样的保证,动作就是幂等的。引用自另一个评论:

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

引用自我的另一个问题的答案:

从历史上看,1999年发布的RFC 2616是被引用最多的HTTP 1.1规范。不幸的是,这为所有这些争论留下了空间。但该规范已被RFC 7231所取代。引用自RFC 7231,第4.2.2节幂等方法,强调我的:

请求方法被认为是“幂等的”;如果达到预期的效果 使用该方法的多个相同请求的服务器是 与单一请求的效果相同。请求方法 由本规范定义,PUT, 删除和安全请求方法 是等幂的> < /强。

所以,在规范中写着,幂等性是关于对服务器的影响。第一个DELETE返回204,然后后续的DELETE返回404,这样不同的状态代码不会使DELETE非幂等的。用这个参数来证明随后的204返回是完全无关的。

这不是幂等性的问题。但接下来的问题可能是,如果我们仍然选择在后续的DELETE中使用204呢?可以吗?

好问题。动机是可以理解的:允许客户端仍然达到预期的结果,而不用担心错误处理。我想说,在随后的DELETE中返回204,基本上是一个无害的服务器端“白色谎言”,客户端不会立即看出区别。这就是为什么有人在野外这样做,而且仍然有效。只要记住,这样的谎言可以被认为是语义上的奇怪,因为“;GET /non-exist"返回404,但“DELETE /non- existent”;给出204,此时客户端会发现你的服务不完全符合第6.5.4节404未找到

但是,RFC 7231暗示的预期方式,即在随后的DELETE操作中返回404,首先应该不是问题。许多开发人员选择这样做。这大概是因为,任何实现了HTTP DELETE(或任何HTTP方法)的客户端都不会盲目地假设结果总是成功的2xx。然后,一旦开发人员开始考虑错误处理,404 Not Found将是首先想到的错误之一。在这一点上,他/她可能会得出一个结论,即HTTP DELETE操作忽略404错误在语义上是安全的。问题解决了。

假设我们必须管理由idnamecity表示的足球队。

{
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请求也是幂等的。