如何在REST API中为"未准备好,稍后再试"选择HTTP状态代码?

JCC*_*CyC 143 language-agnostic rest http http-status-codes batch-processing

我正在开发一个RESTful API,其中http://server/thingyapi/thingyblob/1234返回与thingy#1234相关联的文件(也称为"blob")以进行下载.但可能是请求是在服务器中不存在文件的情况下进行的,但绝大多数情况下都会在以后提供.服务器中有一个批处理过程,可以为所有东西生成所有blob.Thingy 1234已经存在,其数据(blob除外)已经可用.服务器还没有生成东西1234的blob.

我不想要回归404; 那是不存在的东西.这是一个存在的东西,但它的blob尚未生成.有点像YouTube视频的"处理".我认为重定向代码也不合适; 没有"其他"网址可供尝试.

在这种情况下返回的HTTP状态代码是什么?

mat*_*sev 71

我建议202 - Accepted.从文档:

该请求已被接受处理,但处理尚未完成.[...]其目的是允许服务器接受对其他进程的请求(可能是每天只运行一次的面向批处理的进程)

  • -1:这对于启动最终创建"thingy#1234"的进程的请求是有意义的,但不适用于之后为"thingy#1234"本身发出的GET请求.特别地,202建议作为GET请求的结果,服务将在稍后的时间点发送"thingy#1234"的数据.这根本不正确. (58认同)
  • 它还说:"通过此响应返回的实体应该包括请求的当前状态的指示,以及指向状态监视器的指针或用户可以期望满足请求的某些估计."所以这将是一个让客户知道blob还没有准备就绪的好方法,以及找出它什么时候准备就绪的方法. (7认同)
  • 我认为"接受处理"表示您将保存请求以便稍后执行.如果它被忽略,您应该返回4xx或5xx代码,以向客户表明他们可能想再试一次. (3认同)
  • 不能更不同意这个答案。服务器没有返回任何东西,也没有计划(因为这个请求不做任何处理——无论如何它不应该用于 GET)。因此,资源以某种方式对客户端不可用。这应该被视为错误,因此没有 2XX 代码是合适的。4XX 或 5XX 空间中的东西。该请求*未* _“已被接受进行处理”_,该请求实际上已被丢弃 (3认同)
  • 102(处理)似乎也是一个合理的选择,即使它是在webdav规范中. (2认同)

Rae*_*ald 45

"问题",例如它,在服务器端:客户端已经完成了一个良好的请求,但服务器无法满足它.所以我倾向于"服务器错误",5xx状态代码.答曰标准:

以数字"5"开头的响应状态代码表示服务器知道它已经错误或无法执行请求的情况......服务器应该包括一个实体[指示]它是暂时的还是永久的.

注意

  • "错误无法执行请求":尽管标题为"服务器错误",但它们不仅仅是出于服务器错误.
  • " 临时或永久":这些代码适用于暂时不可用的资源,例如您的资源.

在可用的代码中,我会说503,"服务不可用"是最合适的:

由于服务器的临时过载或维护,服务器当前无法处理请求.这意味着这是一个暂时的条件,经过一段时间的延迟后会得到缓解.如果已知,则可以在Retry-After报头中指示延迟的长度.如果没有给出Retry-After,客户端应该像处理500响应一样处理响应.

注意:

  • "暂时的情况会在一段时间后缓解":对你的情况来说是真实的.
  • "暂时超载":对你的情况并非迂腐.但是,可以说,如果您的服务器速度更快,当客户端发出请求时批处理就已经完成了,所以它一种"重载":客户端要求的资源比服务器可以做得更快他们可以.
  • "客户端应该像处理500响应一样处理响应.":这是"内部服务器错误",即服务器因错误而失败时的响应类型.该标准似乎暗示一个很乖的客户应该不会在这种情况下重试.重试适用于您的服务,因此您的回复应包含Retry-After值.您可以提供下次执行批处理的估计完成时间或批处理的执行间隔作为值.

定义您自己的5xx状态代码(例如591)虽然允许,但语义错误:

HTTP状态代码是可扩展的...应用程序必须理解任何状态代码的类,如第一个数字所示,并将任何无法识别的响应视为等同于该类的x00状态代码

客户端会将您自己的状态代码视为500,"内部服务器错误",(如上所述)不正确.

  • @JCCyC你的博客提供了一个很好的案例,可以回复202响应创建内容的请求(POST或PUT).问题似乎在于询问GET的回报. (4认同)
  • 注意:“Retry-After”也可以与 **`307 - TEMPORARY REDIRECT`** 一起使用,如果你想在你的资源“准备好”时强制客户端在其他地方等待,这是很好的 (3认同)
  • 我看不出它比 202 更好:http://benramsey.com/blog/2008/04/http-status-201-created-vs-202-accepted/ (2认同)
  • 这不是服务器的问题。不应使用 5xx 代码。用例是系统的预期和有效状态。部分生成的记录与部分功能的服务器不同。客户端也没有问题。他们要求在某个时刻存在的有效资源。不应使用 4xx 代码。服务器的响应应该是“好的,但我仍在处理它”(202 已接受)。 (2认同)
  • @JaredDeckard 不,不能同意 202 - 除非更改端点的文档。如果终点是“给我x”,那么不,我们不会给你x,而给予x也不是一个可以稍后完成的“过程”。但是,如果端点被描述为“准备资源 y 的表示 x”,那么服务器正在以客户端请求的形式准备已经存在的资源,但尚未准备好。不过我想补充一点,5xx 错误并不意味着服务器出现了您似乎暗示的问题。503 意味着客户端“应该”重试。 (2认同)

Fer*_*ega 25

我认为423 - Locked可以用于此目的:

423(已锁定)状态代码表示方法的源或目标资源已锁定.这个响应应该包含一个适当的前提条件或后置条件代码,例如'lock-token-submitted'或'no-conflicting-lock'.

  • 也许是因为它是一个WebDAV HTTP代码? (9认同)
  • 从 akka-http 中,有 StatusCode RetryWith = reg(c(449)("Retry With", "The request should be retried after Do theproperty action.")) 其中操作将是等待并重试 (2认同)
  • 在很多方面我都同意这一点。我有类似的情况(在我的情况下,从可能尚未填充的索引中搜索)。从语义上讲,我认为这是正确的。但是,423 的 RFC 声明_“此响应应该包含适当的前置条件或后置条件代码,例如'lock-token-submitted' 或'no-conflicting-lock'。”_ 不确定如何在此处应用。就我个人而言,我会选择 409 Conflict,但在没有评论的情况下被否决了 - 不知道为什么? (2认同)

Bri*_*lly 19

另一种选择:503 - Service Unavailable.

  • [根据W3C](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)这不是你想对客户说的话(虽然它意味着"以某种方式再来"):"由于服务器的临时过载或维护,服务器当前无法处理请求.这意味着这是一个临时条件,在一段延迟后会缓解.如果已知,延迟的长度可以在重试中指示 - 标题后.如果没有给出Retry-After,客户端应该像处理500响应一样处理响应." (5认同)
  • 服务不可用,服务可用,但处理未完成。因此503可能不是一个好主意。 (2认同)

fun*_*oll 19

我不想要回归404; 那是不存在的东西.

该URL与对thingy的请求不对应.

http://server/thingyapi/thingyblob/1234

客户端正在请求一个不存在的thingyblob.如果它存在,你会把它给它们.

404.

  • 我很高兴有人这么说!我不敢相信有这么多人认为“503”是一个合适的回应。更不用说其他一些奇怪的建议了。 (5认同)
  • 人们已经变得过于适应404意味着页面未被发现在API的上下文中它们无法在逻辑上分离. (4认同)
  • 这是 sooooo 404。Thingyblob 还不存在,或者永远不存在。对于 http 来说,如果它可用的话,它是无关紧要的。目前它不存在,并且是 404。它何时可用是另一个问题,可以通过从服务器向客户端推送消息来解决,内容为 thingyblob: 1234 available。再次执行获取,瞧.. (3认同)
  • 我认为这是最好的答案。您可以在 404 响应中返回正文。身体可能表明该东西将在稍后的日期提供。或者也使用 Retry-After 标头。该标准在这里需要稍微扩展一下,因为它不能很好地涵盖这种情况。 (2认同)

ska*_*lee 16

由于您的资源尚未就绪,您可能知道何时(大约)它可用以及客户何时可以重试其请求.这意味着您可能希望使用Retry-After标头.此标头对503(服务不可用)有效,这意味着整个站点已关闭以进行维护,并且3xx(重定向)响应.

在我看来302(发现)有Retry-After标头将是最好的选择,但我不确定响应标头的位置字段是否可以等于请求网址.无论如何,它是循环重定向.

  • 即使允许,如果客户端尚未实现对Retry-After标头的支持,则对同一页面的3xx重定向可能最终以503 ...结尾(当然可选地使用Retry-After标头) (3认同)

小智 6

409冲突

指示由于请求中的冲突而无法处理该请求,例如在多次更新的情况下发生编辑冲突。[资料来源Wikipedia。]

这可能是适当的。

如果您无法通过返回数据来满足请求-那么它就不会成功。我认为202建议服务器已将请求排队,并且稍后将满足该请求。但是对于您而言,该请求现在是数据请求,但已失败。如果稍后重试,则是另一个请求。

我认为您有冲突..您想要数据..但正在编辑/更新。如果Thingy1234已经存在并且之前已成功下载,但现在正在进行编辑,那么在进行编辑时将不可用,情况也将如此。

  • @Adam我认为“用户也许能够解决冲突”的含义是,除了等待之外,重新提交的某些内容会有所不同。 (4认同)
  • 不知道为什么这被否决了。似乎对我来说是正确的答案。来自RFC:_“ 409(冲突)状态代码表示由于与目标资源的当前状态发生冲突而无法完成请求。此代码用于用户可能能够解决冲突的情况并重新提交请求。_“您请求了服务器无法返回的资源,因为服务器正在更新该资源-即由于该资源的当前状态。客户端可以通过等待并重新提交来解决此问题 (2认同)