如果POST成功但不会导致创建任何新内容,我们应该返回什么状态代码?

时间:2017-04-10 16:03:29

标签: rest http http-status-codes

我们有一个端点,当您发布创建新版本的资源并返回201以及新创建的资源的位置时。它根据当前版本与发布版本的比较确定新版本号(使用类似规则集的semver)。

如果您发布的版本与现有版本相同,则不会更新版本号。在这种情况下我们应该回报什么?

  • 即使我们没有在技术上创造任何东西,我们也可以返回201.
  • 我不想返回409因为它不是真正的冲突,就像你发布具有相同id的东西一样。如果您在现有版本稍有不同时发布了同样的内容,那么您很乐意获得201。
  • 我们可以返回200,但那样看起来很奇怪,并且会增加用户必须处理的响应代码

201响应的幂等性是否重要?

有更好的建议吗?

8 个答案:

答案 0 :(得分:2)

303怎么样 - 见其他?似乎很合适。我提请你注意这句话 来自https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

的规范
  

此方法主要用于允许输出POST激活的脚本以将用户代理重定向到选定的资源。

这听起来像你想对我做的。这是其余部分。

10.3.4 303见其他

可以在不同的URI下找到对请求的响应,并且应该使用该资源上的GET方法检索。此方法主要用于允许输出POST激活的脚本以将用户代理重定向到选定的资源。新URI不是最初请求的资源的替代引用。 303响应绝不能被缓存,但对第二个(重定向)请求的响应可能是可缓存的。

不同的URI应该由响应中的Location字段给出。除非请求方法是HEAD,否则响应的实体应该包含一个带有指向新URI的超链接的短超文本注释。

  Note: Many pre-HTTP/1.1 user agents do not understand the 303
  status. When interoperability with such clients is a concern, the
  302 status code may be used instead, since most user agents react
  to a 302 response as described here for 303

答案 1 :(得分:2)

我对其他答案感到有些困惑,因为有些人认为几乎正确。所以,让我们稍微澄清一下。如果所有请求确实都是使用POST方法执行的,则在ReSTfulness的上下文中,它们应该修改目标服务器上的状态。否则,POST的含义有点放松,您可以在RFC 7231, sec. 4.3.3中看到。

由于请求的目的是创建新版本的资源,如果已存在具有给定演示文稿的版本,则它们失败。这将取消任何2xx级响应代码的资格。来自section 6.3

  

2xx(成功)状态代码类表示客户的请求已成功接收,理解和接受。

如果你绝对想要,你可以去202/Accepted,这是“故意不置可否”。不过,这有点延伸,因为此状态代码用于排队处理。我会反对它。

其他人建议的204/No Content代码是一个糟糕的选择。但是,如果您POST对您正在更新的资源进行了更新,那么这绝对是正确的。

结果既不是信息(1xx)也不是服务器的故障(5xx)。我们先来看看3xx课程。来自section 6.4

  

3xx(重定向)类状态代码表示用户代理需要采取进一步的操作才能完成请求。

其中最突出的一个是304/Not Modified。虽然听起来非常合适,但遗憾的是,此代码不适用于此。它只能在响应条件GETHEAD请求时返回。

302/Found听起来可能是次佳选择。但是,此代码用于临时重定向,这可能不是您想要的。

正如这里所建议的,303/See Other确实是一个不错的选择:

  

303(请参阅其他)状态代码表示服务器正在将用户代理重定向到另一个资源[...],该资源旨在提供对原始请求的间接响应。   [...]   此状态代码适用于任何HTTP方法。它主要用于允许输出POST操作以将用户代理重定向到选定的资源

所有其他3xx代码正在处理与此处情况几乎无关的各种形式的重定向。

最后看,4xx级的状态代码。来自RFC 7231, sec. 6.5

  

状态代码的4xx(客户端错误)类表示客户端似乎有错误。除了在响应HEAD请求时,服务器应该发送一个表示,其中包含错误情况的解释,以及它是暂时的还是永久的。这些状态代码适用于任何请求方法。

这些实际上很少与申请机构有关。其中两个人会在这里脱颖而出:一个是400/Bad Request,这在设计上过于宽泛。这是 - 如果你愿意 - 一个全能的解决方案。但是,这意味着请求正文在某种程度上是畸形的(如在语法上不正确),这可能不是这种情况。

更有趣的是409/Conflict。来自RFC(强调我的):

  

409(冲突)状态代码表示由于与目标资源的当前状态冲突而无法完成请求

定义的措辞将此代码放在PUT方法附近,但不是唯一的。重申4xx代码的定义:

  

这些状态代码适用于任何请求方法。

422/Unprocessable Entity是一个竞争者,但它意味着语义错误,这里的情况并非如此。

最终(鼓号)最后一块拼图可以在section 4.3.3中找到:

  

如果处理POST的结果等同于现有资源的表示,则源服务器可以通过使用位置字段中的现有资源标识符发送303(请参阅其他)响应来将用户代理重定向到该资源

注意“MAY”。所以你真的可以在303和409之间选择。我觉得409更合适,因为很明显早先的请求引入了一个与当前状态不兼容的状态。 OTOH,303可能是politer方式,更接近标准。无论哪种方式,作为您的API的消费者,我真的想知道我的请求是否失败。无论如何都没有任何效果。

答案 2 :(得分:1)

如果操作未创建任何内容,则201不适用于此:

  

6.3.2. 201 Created

     

201(已创建)状态代码表示已完成请求并导致创建了一个或多个新资源。 [...]

如果操作成功,请参阅下面的一些选项:

  

6.3.1. 200 OK

     

200(OK)状态代码表示请求已成功。在200响应中发送的有效负载取决于请求方法。对于本规范定义的方法,有效载荷的预期含义可以概括为:

     

[...]

     
      
  • POST:表示行动的状态或结果;
  •   
     

[...]

     

除了对CONNECT的响应之外,200响应始终具有有效负载,尽管源服务器可以生成零长度的有效负载主体。如果不需要有效载荷,则原始服务器应该发送204(无内容)。 [...]

  

6.3.5. 204 No Content

     

204(无内容)状态代码表示服务器已成功完成请求,并且在响应有效负载正文中没有要发送的其他内容。 [...]

如果操作失败:

  

6.5.1. 400 Bad Request

     

400(错误请求)状态代码表示服务器无法处理请求,因为某些内容被认为是客户端错误(例如,格式错误的请求语法,无效的请求消息框架或欺骗性请求路由)。

  

11.2. 422 Unprocessable Entity

     

422(不可处理的实体)状态代码表示服务器理解请求实体的内容类型(因此415(不支持的媒体类型)状态代码不合适),以及请求实体是正确的(因此400(错误请求)状态代码是不合适的)但无法处理包含的指令。例如,如果XML请求主体包含格式正确(即语法正确)但语义错误的XML指令,则可能会出现此错误情况。

答案 3 :(得分:0)

我不认为对于这种情况,幂等性是一个问题,因为系统的状态与inicial请求中的状态不同,因为实体现在存在,因此您可以使用不同的代码进行响应

200应该没问题,但你说的有点奇怪。

我从来没有使用过这个,但是我知道在某些情况下你应该用302重定向,为其他资源做一个get,在这种情况下我觉得这个适用,返回一个302并且指向旧的semver,假设您有此实体的get端点。

答案 4 :(得分:0)

如果POST资源具有相同的版本号但数据不同,那么409将适合。但是,如果数据与已存储的数据相同,则可能不需要409。通过消除过程,我会说200 OK没问题。

  

我们可以返回200,但那样看起来很奇怪,并增加了用户必须处理的响应代码

如果这是一个代价高昂的问题,请考虑删除201,而不是200。事实上,对于任何体面复杂的服务,在某些情况下可能存在20X(其中X不为0)适用的情况。这是否意味着我们会记住每个20X响应的代码,并花时间检查我们的服务是否有20X优先于200的情况?我怀疑不是。因此,除非有特定原因以20X回复,例如处理特定用例,否则只需使用200并减少所需的编码和记录量。我怀疑大多数情况下,主叫客户端并不关心。

答案 5 :(得分:0)

最终,正确的答案可能取决于客户端消耗API的情况。如果你也在建立客户,你可以做任何你喜欢的事情......(只是不要太疯狂。)

假设您正在编写API和客户端

我的意见/建议是......

  • 如果 IS 新版本号:201 HTTP状态代码将适合。
  • 如果有 NOT 新版本号:200204 HTTP状态代码适合。
  • 如果知道版本号已更改或相同,则客户端没有任何好处:发送200 HTTP状态代码。

如果您不控制使用您的API的客户:显然会遵循他们的期望。

您可能还希望查看HTTP RFC规范中的所有HTTP Status Codes。以上状态代码也直接链接到相关部分。

答案 6 :(得分:0)

毫无疑问,每当您创建新资源时都应使用201 Created

HTTP Method Definitions RFC中所定义,如果操作未根据响应正文内容创建新资源,则200 Ok204 No Content是适当的响应。

  

POST方法执行的操作可能不会产生资源   可以通过URI识别。在这种情况下,200(OK)或204   (No Content)是适当的响应状态,具体取决于是否   或不响应包括描述结果的实体。

     

如果已在源服务器上创建资源,则为响应   应该是201(创建)并包含一个描述该实体的实体   请求的状态,并引用新资源和位置   标题(见第14.30节)。

现在,回到原来的问题,即当操作成功并且无法返回时要使用什么,您应该使用204 No Content。此状态代码专门用于已成功完成请求的操作但没有服务器可提供的其他相关信息的情况。

  

204(无内容)状态代码表示服务器已成功完成请求,并且没有其他内容可在响应有效负载正文中发送。

答案 7 :(得分:0)

201:创建新版本时

202:更新现有版本时

204:当接受请求但未完成处理时

by def,204 = No Content

  

服务器已完成请求但不需要返回   entity-body,可能想要返回更新的元信息。该   响应可能包括新的或更新的元信息形式   实体标题,如果存在,应该与...相关联   要求的变体。

     

如果客户端是用户代理,它不应该更改其文档视图   从导致请求发送的那个。这个回应是   主要是为了允许在没有的情况下进行动作的输入   但是,导致更改用户代理的活动文档视图   任何新的或更新的元信息应该应用于文档   目前在用户代理的活动视图中。

     

204响应绝不能包含消息体,因此总是如此   由标题字段后的第一个空行终止。

因此,它与您的需求略有不同,但我认为它最合适。