使用http DELETE删除资源


122

因此,鉴于Http中的DELETE动词是幂等的,因此当我发出以下请求时,第二个(或第三个或第四个,等等)会发生什么?

DELETE /person/123

第一次,资源被删除,并且我返回204(成功,没有内容)。我应该在后续调用中返回204还是返回404(未找到)?

Answers:


152

由于无状态系统中的HTTP请求应该是独立的,因此一个请求的结果不应依赖于先前的请求。考虑如果两个用户同时对同一资源执行DELETE操作,该怎么办。第二个请求获得404是有意义的。如果一个用户发出两个请求,则同样如此。

我猜想让DELETE返回两个不同的响应对您来说并不是幂等的。我发现将幂等请求视为使系统保持相同状态(不一定具有相同的响应)很有用。因此,无论您是删除现有资源还是尝试删除不存在的资源,服务器资源状态都是相同的。


4
谢谢。这很有意义。我确实在想幂等会返回相同的响应。
克雷格·威尔逊

4
@克雷格小心!在食谱中,Subbu与我刚才所说的完全矛盾。他说,幂等意味着它应该返回相同的响应。幸运的是,Subbu将参加RESTFest,因此,我将在那里与他澄清。
Darrel Miller

57
如果删除不存在的内容,则应仅返回204(即使资源从不存在)。客户希望资源消失了,资源也消失了。返回404将暴露对客户端不重要的内部处理,这将导致不必要的错误情况。
布莱恩(Brian)

9
@DarrelMiller我想这里的关键概念是您不应该使用DELETE来检查资源是否存在,您应该首先使用GET。然后,如果响应为200,则执行DELETE; 否则甚至不必理会。因此,我认为始终在DELETE上返回204是有意义的。
manei_cc 2015年

10
@Brian RFC表示其行为应类似于rmrm如果不存在,则返回错误。 tools.ietf.org/html/rfc7231#section-4.3.5
Dax

32

RESTful Web服务指南是此的绝佳资源。一次偶然的机会,它的Google预览显示了有关DELETE的页面(第11页):

DELETE方法是幂等的。这意味着即使服务器删除了先前请求中的资源,服务器也必须返回响应代码200(确定)。但是实际上,将DELETE实现为幂等操作需要服务器跟踪所有已删除的资源。否则,它可以返回404(未找到)。


是的,这看起来像是很棒的资源。但是,DELETE部分对我而言并不重要(它是第23页,并且已编辑了该预览)。你读过这本书吗?您碰巧知道我的问题的答案吗?
克雷格·威尔逊

本书是构建REST的必备书(特别讲的不是语言)。
yves amsellem

7
@Craig阅读本食谱时,即使您已删除它,也应返回200 OK。但是,实际上,这将要求服务器跟踪所有已删除的资源,因此,您可以使用404。接着说,出于安全考虑,您可能始终需要返回404。Page 11
Darrel Miller

+1其次,强烈推荐用于设计RESTful服务的书。
Paul DelRe 2011年

18
好吧,这本书是错误的。幂等并不意味着状态码将相同。重要的是服务器的最终状态。
朱利安·雷施克

13

我同意当前选择的答案,即第二(和第三,第四,...)DELETE应该得到404。而且,我注意到答案得到143票赞成,但也有相反的评论,票数为54票赞成,因此该社区按大约3:1的比例分为两个阵营。这是解决长期辩论的更多信息。

  1. 首先,让我们从“我”的想法,“您”的想法或另一本书的作者的想法开始。让我们从HTTP规范即RFC 7231开始。

    • RFC 7231的4.3.5节中仅提到成功的响应应为2xx,但并未指出后续的DELETE将得到什么。因此,让我们深入研究。
    • RFC 7231第6.5.4节“找不到 404”表示404响应是针对资源不存在的。由于没有调用任何特定的http方法(特别是DELETE),否则我们可以直观地得到一个印象(正确的说),即我的请求DELETE /some/resource/which/does/not/existDELETE /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返回20​​4,然后随后的DELETE返回404,这种不同的状态代码不会使DELETE成为非等幂的。使用此参数来证明随后的204返回是完全无关的。

  2. 好,所以这与幂等无关。但是接下来的问题可能是,如果我们仍然选择在后续的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错误在语义上是安全的。他们这样做了。

问题解决了。


2
+1“幂等性完全取决于对服务器的影响”。认真回答。做得好!我是后续DELETE请求的404信徒。
nwayve

11

第一次删除:200或204。

随后的DELETE:200或204。

理由:删除应该是幂等的。如果您在第二个DELETE上返回404,则您的响应将从成功代码更改为错误代码。客户端程序可能会基于DELETE失败的假设采取错误的措施。

范例

  • 假设您的DELETE操作是由客户端程序执行的多步操作(或“传奇”)的一部分。
  • 客户端程序例如可以是执行银行交易的移动应用程序。
  • 假设客户端程序对DELETE操作具有自动重试功能(这很有意义,因为DELETE应该是幂等的)。
  • 假设第一个DELETE已成功执行,但是200响应在进入客户端程序的过程中丢失了。
  • 客户端程序将重试DELETE。
  • 如果第二次尝试返回404,则由于该错误代码,客户端程序可能会取消整个操作。
  • 但是,因为第一个DELETE在服务器上成功执行,所以系统可能处于不一致状态
  • 如果第二次尝试返回200或204,则客户端程序将按预期进行。

仅为了说明这种方法的用法,用于PayPalHTTP API样式指南具有以下准则:

删除:此方法应返回状态码204,因为在大多数情况下无需返回任何内容,因为请求是删除资源并且已成功删除该资源。

由于DELETE方法也必须是幂等的,即使资源已被删除,它仍应返回204。通常,API使用者不关心资源是否作为此操作的一部分或之前的内容被删除。这也是为什么应返回204而不是404的原因。


1
问题是,对于客户端来说重要的是,删除了资源,或者资源已被删除。如果某些其他客户端在传奇中删除了资源该怎么办。考虑到客户目标已经实现,您真的要失败吗?
Darrel Miller

1
@DarrelMiller好点。更重要的取决于业务环境。但总的来说,我宁愿在第二次DELETE尝试上返回204,即使该资源已被另一个客户端删除。考虑到实现了客户目标,我不希望服务失败(即404)。
Paulo Merson

2
正如其他人提到的那样,幂等性不是您的响应代码,而是您的服务器状态。
Niranjan

@Niranjan我同意幂等性与服务器状态有关,但是不同的响应代码可能会通过取消正在进行的传奇来驱动客户端不必要地更改服务器状态。
Paulo Merson

@Paulo Merson如果客户要求删除从未存在的项目,您将返回什么代码?204?还是404?如果您始终返回204,检查返回码有什么意义?
frenchone
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.