鉴于HTTP中的DELETE动词是幂等的,当我发出以下请求时,第二次(或第三次、第四次等)应该发生什么?
DELETE /person/123
第一次,资源被删除并返回204(成功,无内容)。在随后的调用中,我应该返回204还是404(未找到)?答案:取决于你对API的设计,如果你的API旨在让客户端知道资源的存在或不存在,那么在随后的调用中应该返回404;如果你的API旨在让客户端知道资源已经被删除了,那么在随后的调用中应该返回204。
鉴于HTTP中的DELETE动词是幂等的,当我发出以下请求时,第二次(或第三次、第四次等)应该发生什么?
DELETE /person/123
第一次,资源被删除并返回204(成功,无内容)。在随后的调用中,我应该返回204还是404(未找到)?在无状态系统中,由于HTTP请求应该是独立的,因此一个请求的结果不应该依赖于前一个请求。考虑一下如果两个用户同时对同一资源进行删除操作会发生什么。第二个请求返回404是有意义的。如果一个用户发出两个请求,也应该是如此。
我猜想,让DELETE请求返回两个不同的响应对您来说可能感觉不幂等。我认为将幂等请求看作使系统保持相同状态更有用,而不一定要求得到相同的响应。因此,无论您删除现有资源还是尝试删除不存在的资源,服务器资源状态都是相同的。
rm
命令一样运作。如果文件不存在,则rm
会返回一个错误。https://tools.ietf.org/html/rfc7231#section-4.3.5 - Dax FohlDELETE /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
会有所不同呢?
“但幂等性呢?!”我听到你在尖叫。等一下,我们将进入这个问题。
历史上,RFC 2616于1999年发布,是HTTP 1.1规范中最常被引用的。不幸的是,其关于幂等性的描述很模糊,这留下了所有这些争论的余地。但是,该规范已被RFC 7231取代。引用自RFC 7231,section 4.2.2 Idempotent Methods,强调我的:
因此,规范中写明了幂等性与服务器上的效果有关。第一个DELETE返回204,然后随后的DELETE返回404,这些不同的状态代码并不会使DELETE变得不幂等。用这个论点来证明随后的204返回是毫无意义的。如果使用该方法进行多个相同请求的预期效果对服务器的影响与单个此类请求的效果相同,则认为请求方法是“幂等”的。在本规范中定义的请求方法中,PUT、DELETE和安全请求方法是幂等的。
GET /non-exist
返回404,但DELETE /non-exist
返回204,此时客户端会发现你的服务并没有完全遵守section 6.5.4 404 Not Found。但是我想指出,RFC 7231暗示的预期方式,即在随后的DELETE中返回404,本质上不应该成为问题。有3倍以上的开发者选择这样做,你有听说过由于客户端无法处理404而导致的重大事件或投诉吗?大概是没有的,因为任何实现HTTP DELETE(或任何HTTP方法)的体面客户端都不会盲目地假定结果总是成功的2xx。然后,一旦开发人员开始考虑错误处理,404 Not Found将是首先想到的错误之一。此时,他/她可能会得出结论,对于HTTP DELETE操作忽略404错误是语义上安全的。他们就这样做了。问题解决了。GET /non-exist
返回404,但 DELETE /non-exist
返回204_。" - aalaapRESTful web服务食谱是这方面的一份很好的资源。偶然间,它的谷歌预览显示了有关DELETE(第11页)的页面:
DELETE方法是幂等的。这意味着服务器必须返回响应代码200(OK),即使服务器在以前的请求中已删除资源。但在实践中,将DELETE实现为幂等操作需要服务器跟踪所有已删除的资源。否则,它可能会返回404(未找到)。
首次DELETE: 返回200或204。
后续DELETE: 返回200或204。
原因: DELETE应该是幂等的。如果第二个DELETE返回404,则您的响应将从成功代码更改为错误代码。客户端程序可能会根据DELETE失败的假设采取不正确的操作。
示例:
只是为了说明这种方法的使用,PayPal的HTTP API风格指南有以下指南:
DELETE:在大多数情况下,此方法应返回状态代码204,因为没有必要返回任何内容,请求是删除资源,并且已成功删除。
由于DELETE方法也必须是幂等的,因此即使资源已被删除,它仍应返回204。通常API使用者并不关心是否将资源作为此操作的一部分或之前已删除。这也是应返回204而不是404的原因。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404
因此,我建议在操作成功时使用200,在资源缺失时使用404。这还可以帮助管理测试用例,以确保正确的实施。