Answers:
由于无状态系统中的HTTP请求应该是独立的,因此一个请求的结果不应依赖于先前的请求。考虑如果两个用户同时对同一资源执行DELETE操作,该怎么办。第二个请求获得404是有意义的。如果一个用户发出两个请求,则同样如此。
我猜想让DELETE返回两个不同的响应对您来说并不是幂等的。我发现将幂等请求视为使系统保持相同状态(不一定具有相同的响应)很有用。因此,无论您是删除现有资源还是尝试删除不存在的资源,服务器资源状态都是相同的。
RESTful Web服务指南是此的绝佳资源。一次偶然的机会,它的Google预览显示了有关DELETE的页面(第11页):
DELETE方法是幂等的。这意味着即使服务器删除了先前请求中的资源,服务器也必须返回响应代码200(确定)。但是实际上,将DELETE实现为幂等操作需要服务器跟踪所有已删除的资源。否则,它可以返回404(未找到)。
我同意当前选择的答案,即第二(和第三,第四,...)DELETE应该得到404。而且,我注意到答案得到143票赞成,但也有相反的评论,票数为54票赞成,因此该社区按大约3:1的比例分为两个阵营。这是解决长期辩论的更多信息。
首先,让我们从“我”的想法,“您”的想法或另一本书的作者的想法开始。让我们从HTTP规范即RFC 7231开始。
DELETE /some/resource/which/does/not/exist
应DELETE /some/resource/which/happened/to/be/removed/by/someone/else/five/days/ago
返回404。然后,还可能返回404那么,为什么应该DELETE /some/resource/i/deleted/five/seconds/ago
有什么不同呢?“但是,幂等呢?!”,我听到你在尖叫。等等,我们即将开始。从历史上看,1999年发布的RFC 2616是引用最多的HTTP 1.1规范。不幸的是,它对幂等性的描述很模糊,为所有这些辩论留出了空间。但是该规范已被RFC 7231取代。引自RFC 7231中的4.2.2幂等方法,重点是:
如果使用该方法的多个相同请求在服务器上的预期效果与单个此类请求的效果相同,则该请求方法被视为“幂等”。 在本规范定义的请求方法中,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未找到”将是第一个想到的错误之一。到那时,他/她可能会得出一个结论,即HTTP DELETE操作忽略404错误在语义上是安全的。他们这样做了。
问题解决了。
第一次删除:200或204。
随后的DELETE:200或204。
理由:删除应该是幂等的。如果您在第二个DELETE上返回404,则您的响应将从成功代码更改为错误代码。客户端程序可能会基于DELETE失败的假设采取错误的措施。
范例:
仅为了说明这种方法的用法,用于PayPal的HTTP API样式指南具有以下准则:
删除:此方法应返回状态码204,因为在大多数情况下无需返回任何内容,因为请求是删除资源并且已成功删除该资源。
由于DELETE方法也必须是幂等的,即使资源已被删除,它仍应返回204。通常,API使用者不关心资源是否作为此操作的一部分或之前的内容被删除。这也是为什么应返回204而不是404的原因。