鉴于 HTTP 中的 DELETE 动词是幂等的,当我发出以下请求时,我第二次(或第三次,或第四次等)会发生什么?
DELETE /person/123
第一次,资源被删除,我返回204(成功,无内容)。我应该在后续调用中返回 204 还是返回 404(未找到)?
鉴于 HTTP 中的 DELETE 动词是幂等的,当我发出以下请求时,我第二次(或第三次,或第四次等)会发生什么?
DELETE /person/123
第一次,资源被删除,我返回204(成功,无内容)。我应该在后续调用中返回 204 还是返回 404(未找到)?
由于无状态系统中的 HTTP 请求应该是独立的,因此一个请求的结果不应依赖于前一个请求。考虑如果两个用户同时对同一资源执行 DELETE 会发生什么。第二个请求获得 404 是有意义的。如果一个用户发出两个请求,情况也是如此。
我猜让 DELETE 返回两个不同的响应对您来说并不具有幂等性。我发现将幂等请求视为使系统处于相同状态是很有用的,不一定具有相同的响应。因此,无论您是删除现有资源,还是尝试删除不存在的资源,服务器资源状态都是相同的。
我同意当前选择的答案所说的,第二个(和第三个,第四个,...) DELETE 应该得到一个 404。而且,我注意到答案有 143 票,但也有相反的评论,有 54 票,因此社区以大约 3:1 的比例分为 2 个阵营。这里有更多信息来解决这场长期争论。
RFC 7231,第 4.3.5 节 DELETE碰巧只提到成功的响应应该是 2xx,但它没有说明随后的 DELETE 会得到什么。所以让我们更深入地挖掘。
RFC 7231,第 6.5.4 节 404 Not Found说 404 响应是针对不存在的资源。由于没有调用特定的 http 方法(特别是不是 DELETE)以进行其他处理,因此我们可以直观地得到一个印象(这是正确的),我的请求DELETE /some/resource/which/does/not/exist
应该导致 404。然后,DELETE /some/resource/which/happened/to/be/removed/by/someone/else/five/days/ago
还不如返回 404 . 那么,为什么要DELETE /some/resource/i/deleted/five/seconds/ago
有所不同呢?“但是幂等性怎么样?!”,我能听到你在尖叫。等等,我们即将进入。
从历史上看,1999 年发布的 RFC 2616 是引用最多的 HTTP 1.1 规范。不幸的是,它对幂等性的描述是模糊的,这为所有这些辩论留下了空间。但是该规范已被 RFC 7231 取代。引自RFC 7231,第 4.2.2 节 Idempotent Methods,强调我的:
如果使用该方法的多个相同请求对服务器的预期效果与单个此类请求的效果相同,则该请求方法被认为是“幂等的”。 在本规范定义的请求方法中,PUT、DELETE和安全请求方法 是幂等的。
所以,它写在规范中,幂等性就是对服务器的影响。第一个 DELETE 返回 204,然后随后的 DELETE 返回 404,这种不同的状态码不会使 DELETE 非幂等。使用这个论点来证明随后的 204 返回是完全不相关的。
好的,所以这与幂等性无关。但是接下来可能会出现一个问题,如果我们在后续的DELETE中仍然选择使用204呢?可以吗?
好问题。动机是可以理解的:让客户端仍然达到预期的结果,而不用担心错误处理。我想说,在随后的 DELETE 中返回 204 是一个基本上无害的服务器端“善意的谎言”,客户端不会立即说出区别。这就是为什么大约 25% 的人在野外这样做,而且它似乎仍然有效。请记住,这样的谎言在语义上可能被认为是奇怪的,因为GET /non-exist
返回 404 但DELETE /non-exist
给出 204,此时客户端会发现您的服务不完全符合第 6.5.4 节 404 Not Found。
但我想指出,RFC 7231 暗示的预期方式,即在随后的 DELETE 上返回 404,首先不应该是一个问题。选择这样做的开发人员增加了 3 倍,您是否听说过因客户端无法处理 404 导致的重大事件或抱怨?据推测,不,这是因为,任何实现 HTTP DELETE(或任何 HTTP 方法,就此而言)的体面的客户端都不会盲目地假设结果总是成功的 2xx。然后,一旦开发人员开始考虑错误处理,404 Not Found 将是首先想到的错误之一。到那时,他/她可能会得出这样的结论:HTTP DELETE 操作忽略 404 错误在语义上是安全的。他们这样做了。
问题解决了。
RESTful Web 服务说明书是一个很好的资源。偶然地,它的谷歌预览显示了关于 DELETE 的页面(第 11 页):
DELETE 方法是幂等的。这意味着即使服务器在先前的请求中删除了资源,服务器也必须返回响应代码 200(OK)。但在实践中,将 DELETE 实现为幂等操作需要服务器跟踪所有已删除的资源。否则,它会返回 404(未找到)。
第一次删除:200 或 204。
后续删除:200 或 204。
基本原理:DELETE 应该是幂等的。如果您在第二次 DELETE 时返回 404,则您的响应将从成功代码变为错误代码。客户端程序可能会基于 DELETE 失败的假设采取不正确的操作。
示例:
只是为了说明这种方法的使用,PayPal 的 HTTP API 样式指南有以下指南:
DELETE:该方法应该返回状态码 204,因为在大多数情况下不需要返回任何内容,因为请求是删除资源并且已成功删除。
由于 DELETE 方法也必须是幂等的,因此即使资源已被删除,它仍应返回 204。通常,API 使用者并不关心资源是否作为此操作的一部分或之前被删除。这也是为什么应该返回 204 而不是 404 的原因。