如何在REST API中为“尚未就绪,请稍后再试”选择HTTP状态代码?[关闭]


152

我正在开发RESTful API,在其中http://server/thingyapi/thingyblob/1234返回与要下载的东西#1234相关的文件(又称“ blob”)。但是可能是在服务器中不存在该文件时发出请求,但肯定以后提供该文件。服务器中有一个批处理过程,可为所有事物生成所有blob。Thingy 1234已经存在,并且除blob之外的其他数据已经可用。服务器还没有生成东西1234的斑点。

我不想返回404;那是针对不存在的事物。这是一个存在的问题,但尚未生成它的斑点。Kinda喜欢YouTube影片中的「处理中」。我也不认为重定向代码是合适的。没有尝试使用的“其他” URL。

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



7
首先,如果thing 1234还没有任何可获取GET的表示形式,那么它在什么意义上作为资源存在(从客户端的角度来看)?在服务器内部有一个排队的作业来创建1234,这一事实似乎并不意味着资源1234存在。其次,客户端从哪里获得URI ... / thingyblob / 1234?在资源实际上是可获取的之前,服务器可能不应该向客户端提供该URI。
安迪·丹妮

1
一件东西除了斑点外还有其他值得获得的特性。只是斑点需要花费一些时间才能生成。客户端通过例如server / thingyapi / thingy / 1234
JCCyC 2012年

10
HTTP标准提供了有关在哪些情况下使用哪些状态代码的指南。因此,这个问题实际上并不是主要基于观点
拉德瓦尔德

2
如何204“没有内容”?Is表示服务器已经成功处理了请求,并且[此时]未返回任何内容。
Timo

Answers:


77

我建议202 - Accepted。从文档中

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


62
-1:这对于启动最终创建“ thingy#1234”的过程的请求有意义,但对于随后针对“ thingy#1234”本身发出的GET请求却没有意义。特别地,a 202表示作为GET请求的结果,该服务将在稍后的时间点发送“ thingy#1234”的数据。这根本是不正确的。
山姆·哈威尔

7
它还说:“随该响应返回的实体应该包括请求当前状态的指示,以及指向状态监视器的指针或用户何时可以期望完成请求的一些估计。”,所以这将是一个让客户知道Blob尚未准备好的好方法,以及找出何时准备就绪的方法。
雷米·勒博2014年

3
我认为“接受处理”表示您正在保存请求,以便稍后执行。如果只是被忽略,则应返回4xx或5xx代码,以向客户端指示他们可能要重试。
路加福音

3
即使在webdav规范中,有时102(处理)似乎也是一个合理的选择。
akostadinov

2
不能完全不同意这个答案。服务器未返回任何内容,也未计划进行任何操作(由于此请求,因此未进行任何处理-无论如何都不应该对GET进行处理)。这样,资源在某种程度上对客户端不可用。应该将其视为错误,因此不适合使用2XX代码。4XX或5XX空间中的内容。请求已经没有 “被接受处理”,该请求被在实践中被丢弃
亚当

52

这样的“问题”在服务器端:客户端提出了格式正确的请求,但服务器无法满足。因此,我倾向于使用5xx状态代码的“服务器错误”。

Quoth RFC 7231(当前的HTTP标准,已添加重点):

状态代码的5xx(服务器错误)类表示服务器知道服务器已错误或无法执行所请求的方法。除响应HEAD请求外,服务器应发送一个包含错误情况说明以及它是暂时还是永久情况的说明。

注意

  • “错误无法执行请求”:尽管标题为“服务器错误”,但它们不仅仅用于服务器错误。
  • 临时或永久”:这些代码适用于像您这样的暂时不可用的资源。

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

503(服务不可用)状态代码表示服务器当前由于暂时的过载或计划的维护而无法处理该请求,这可能会在某些延迟后得到缓解。服务器可以发送一个Retry-After头域...来建议一个适当的时间,以便客户端在重试请求之前等待。

注意:

  • “经过一段时间的延迟后可能会得到缓解”:适用于您的情况。
  • “临时超载”:在您的情况下不是很真实。但是,可以争辩的是,如果您的服务器要快得多,那么当客户端发出请求时批处理就已经完成了,因此这一种“超载”:客户端请求资源的速度超过了服务器的处理能力他们可用。
  • 重试适合您的服务,因此您的回复应包含一个Retry-After值。您可以提供下一次执行批处理的估计完成时间或批处理的执行间隔作为值。

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

客户端必须理解任何状态代码的类别(如第一位数字所示),并将无法识别的状态代码视为等同于该类别的x00状态代码

客户端会将您自己的状态代码视为500,“ Internal Server Error”,这是不正确的。


2
我看不出它是如何优于202:benramsey.com/blog/2008/04/...
JCCyC

4
@JCCyC您的博客非常适合返回202以响应创建内容的请求(POST或PUT)。问题似乎在询问关于GET返回什么。
拉德瓦尔德2012年

@JCCyC可以看作是不同的未就绪状态:想象一下该资源的一个ajax,您是将202表示为成功状态还是将503表示为错误状态?这样您就可以在应用对响应的响应上下文中隐式地看到您更喜欢的含义
rloth 2016年

我也喜欢“重试之后”的实用方面,它与“未准备好”的东西配合得很好
rloth 2016年

1
注意:“ Retry-After”也可以使用307 - TEMPORARY REDIRECT,如果您想在资源“准备就绪”时强迫客户端在其他地方等待
rloth

28

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

423(锁定)状态代码表示方法的源或目标资源已锁定。该响应应该包含适当的前提条件或后置条件代码,例如“锁令牌提交”或“无冲突锁”。


1
很好的答案!我想知道为什么它没有更多的赞誉。
lex82'6

10
也许是因为它是WebDAV HTTP代码?
斯蒂芬·L

1
在akka-http中,有StatusCode RetryWith = reg(c(449)(“ Retry With”,“执行适当的操作后应重试该请求。”))此处将等待
并重

2
我在很多方面都同意这一点。我有类似的情况(在我的情况下,从可能尚未填充的索引中搜索)。从语义上来说,我认为这是正确的。但是,针对423的RFC声明“此响应应包含适当的前提条件或后置条件代码,例如'提交的锁令牌'或'没有冲突的锁'”。 不知道如何在这里应用它。就我个人而言,我会选择409 Conflict,但这已经被否决了,没有发表评论-不知道为什么吗?
亚当

22

我不想返回404;那是针对不存在的事物。

该网址与对一件东西的请求不符。

http://server/thingyapi/thingyblob/1234

客户端请求的内容不存在。如果存在,您可以将其交给他们。

404。


1
我很高兴有人这么说!我不敢相信有这么多人认为这503是适当的回应。更不用说其他一些奇怪的建议了。
杰森·德罗斯

尽管我同意404是此处最合适的响应,但它并没有回答OP的问题:如何指示何时有可用东西:-)。我认为Retry-After字段似乎是最佳选择,但只能正式用于503和3xx代码。@Jason:我认为这解释了一些奇怪的建议。
罗恩·德伊克斯

我认为这是最好的答案。您可以在404响应中返回正文。该机构可能表示该东西将在以后提供。或也使用Retry-After标头。该标准在这里需要扩展一点,因为它不能很好地涵盖这种情况。
WW。

4
人们已经非常适应404含义页面,因此在API上下文中找不到页面无法逻辑分离。
松饼人

1
这是sooooo404。Thingyblob尚不存在,甚至永远不存在。目前它不存在,它不存在404。何时可用是另一个问题,可以通过将消息从服​​务器推送到客户端sayyblob中来解决:thingyblob:1234可用。再执行一次,瞧
。。– 100r

21

另一种选择:503 - Service Unavailable


5
根据W3C,这不是您要对客户端说的(尽管它以某种方式表示“再次出现”):“由于服务器的暂时超载或维护,服务器当前无法处理该请求。这意味着这是一个暂时的条件,可以在一定的延迟后得到缓解。如果知道,延迟的长度可以在Retry-After标头中指出;如果没有给出Retry-After,则客户端应该像对待500条回应。”
skalee 2013年

4
服务不可用,服务可用,但处理未完成。因此503可能不是一个好主意。
Ishtiaque Khan

17

由于您的资源尚未准备好,您可能知道(何时)该资源何时可用以及客户端何时可以重试其请求。这意味着您可能想利用Retry-After header。该标头与503(服务不可用)一起有效,这意味着整个站点都将停止维护,并且3xx(重定向)响应。

我认为带有Retry-After标头的302(找到)是最好的选择,但是我不确定响应标头的Location字段是否可以等于请求url。无论如何,这是循环重定向。


3
即使允许,如果客户端尚未实现对Retry-After标头的支持,那么到同一页面的3xx重定向最终可能会以503结尾(当然,可选地带有Retry-After标头)
Ron Deijkers 2015年

1
Retry-After在由RFC 6585(2012年4月)添加的HTTP 429“请求过多”中也有效。如果资源尚未准备就绪的原因是客户端一直在给服务器做太多工作,那么这可能是适当的。
西拉斯·布朗

8

409冲突

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

这可能是适当的。

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

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


2
不知道为什么这被否决了。似乎对我来说是正确的答案。从RFC:“ 409(冲突)状态代码表示由于与目标资源的当前状态发生冲突而无法完成请求。此代码用于用户可能能够解决冲突和重新提交请求。 “您请求了服务器无法返回的资源,因为服务器正在更新该资源-即由于该资源的当前状态。客户可以通过等待并重新提交来解决此问题
亚当(Adam)

1
@Adam我认为“用户可能能够解决冲突”的含义是,关于重新提交的内容将有所不同,而不仅仅是等待。
整体开发人员

3

501-未实施

就像听起来一样。尚未实现的功能,但意味着将来的可用性。

这是5xx错误摘要的链接。


4
对于这个问题,听起来好像功能本身存在,但是所请求的项目不存在。
路加福音

在我的答案中,@ Luke 501的链接中的描述是:“ ...它无法满足请求。通常这意味着将来的可用性。这完全满足了OP的要求。无论数据是否存在于他的服务器或数据库中。最终结果是暂时无法通过API进行访问。因此,该API无法满足该请求,但想暗示它将来将通过http代码提供。
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.