REST DELETE是否真的等幂?


165

删除应该是幂等的。

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

如果我再次执行此操作,由于该帐户已不存在,我希望输入404吗?如果我尝试删除一个从未存在的帐户该怎么办?


11
除了答案之外,我建议一般不要过多地关注幂等特征:它不涉及可交换性和并发请求。例如,同一“ R1” PUT请求的N + 1应该具有相同的效果,但是您不知道另一个客户端是否在您的两次请求之间发出了不同的PUT / DELETE“ R2”请求,因此,当n R1 = R1和m R2 = R2,如果仅考虑单个客户端的观点,则在其中交错出现“ R1”和“ R2”请求的情况不一定会“看起来”幂等。
布鲁诺

Answers:


188

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


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

这里

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


键位存在N个副作用> 0相同的请求是相同的单个请求。

您可以正确地预期状态码会有所不同,但这不会影响幂等性核心概念-您可以多次发送请求,而无需对服务器状态进行其他更改。


3
副作用!==服务器状态
2013年

2
@wprl关于这种“副作用”到底是什么存在争论。它可能是“服务器状态”,也可能是发送给客户端的响应。leedavis81.github.io/is-a-http-delete-requests-idempotent
Alireza

这是一个论点,即第二个DELETE上的404实际上可能会更改服务器的状态:stackoverflow.com/a/45194747/317522
Paulo Merson

1
@PauloMerson谢谢,我个人认为第二个返回值是404还是200都不重要,服务器的状态没有改变,所以我对此感到满意。
克里斯·麦考利

46

幂等与请求的效果有关,而不与您获得的响应代码有关。

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

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

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


13

重要的区别是,幂等是指副作用,而不是全部效应或响应。如果执行此操作,DELETE http://example.com/account/123则结果是现在从服务器中删除了帐户123。那是唯一且唯一的效果,唯一且唯一地改变了服务器的状态。现在,假设您DELETE http://example.com/account/123再次执行相同的请求,服务器将做出不同的响应,但是其状态是相同的。

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


7

HTTP RFC

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

请注意,这是“副作用”,而不是“响应”。


7

是。无论响应代码如何。

针对HTTP 1.1的最新RFC(重点是我的):

幂等方法的区别在于,如果在客户端能够读取服务器的响应之前发生通信故障,则可以自动重复请求。例如,如果客户端发送PUT请求并且在接收到任何响应之前关闭了基础连接,则客户端可以建立新连接并重试幂等请求。它知道即使原始请求成功,重复请求也将具有相同的预期效果,尽管响应可能会有所不同。

它明确表示响应可能有所不同。更重要的是,它指出了产生此概念的原因:如果一个动作是幂等的,则客户端可以在遇到任何错误时重复该动作,并知道这样做不会导致任何崩溃。否则,客户端必须再次进行查询(可能是GET),以查看前一个查询是否有效,然后安全地重复执行该操作。只要服务器可以做出这样的保证,动作就是幂等的。引用其他评论

计算幂等性与系统的健壮性有关。由于事情可能会失败(例如,网络中断),因此当检测到故障时,如何恢复?最简单的恢复就是重新执行一次,但这仅在重新执行幂等时才有效。例如discard(x)是幂等的,但pop()不是。都是关于错误恢复的。


2

我认为是404-帐户不存在。

您可以争论400-错误请求。但是就REST而言,您请求对其执行操作的对象不存在。转换为404。


1
要生成400,您必须知道该对象曾经存在,这非常不稳定。
annakata 2010年

1
@ annakata,400甚至不适合曾经存在的资源(也许您记着410 / Gone),它用于错误的请求“由于语法格式错误,服务器无法理解该请求。”
布鲁诺

3
@Bruno-我知道这是什么意思,OP引用了它。
annakata 2010年

1
我认为200可以。您希望服务器状态为该帐户已消失。哪个请求实际上使它消失不重要吗?在第二个请求上它仍然消失了,服务器状态没有改变。
安迪

1

引自我的另一个答案

从历史上看,1999年发布的RFC 2616是引用最多的HTTP 1.1规范。不幸的是,它对幂等性的描述很模糊,为所有这些辩论留出了空间。但是该规范已被RFC 7231所取代。引自RFC 7231中的4.2.2幂等方法,重点是:

如果使用该方法的多个相同请求在服务器上的预期效果与单个此类请求的效果相同,则该请求方法被视为“幂等”。 在本规范定义的请求方法中,PUT,DELETE和安全请求方法 是幂等的

因此,它写在规范中,幂等性完全是对服务器的影响。第一个DELETE返回20​​4,然后后续的DELETE返回404,这样的不同状态代码不会使DELETE成为非幂等的。使用此参数来证明随后的204返回是正确的,这根本不相关。


好,所以这与幂等无关。但是接下来的问题可能是,如果我们仍然选择在后续的DELETE中使用204,该怎么办?可以吗

好问题。动机是可以理解的:允许客户仍然达到预期的结果,而不必担心错误处理。我要说的是,在后续的DELETE中返回204,这在很大程度上是服务器端的“白色谎言”,客户端不会立即告诉别人。这就是为什么有人在野外这样做并且仍然有效的原因。请记住,这种谎言在语义上可能是奇怪的,因为“ GET /不存在”返回404,而“删除/不存在”给出204,此时客户会发现您的服务不完全符合第6.5.4节404未找到

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.