ChatGPT解决这个技术问题 Extra ChatGPT

哪个 HTTP 状态代码表示“尚未准备好,稍后再试”? [关闭]

关闭。这个问题是基于意见的。它目前不接受答案。想改进这个问题?更新问题,以便可以通过编辑这篇文章用事实和引用来回答它。 6年前关闭。本帖上个月已编辑提交审核,未能重新打开该帖:原始关闭原因未解决 改进此问题

我正在开发一个 RESTful API,其中 http://server/thingyapi/thingyblob/1234 返回与要下载的项目 #1234 关联的文件(又名“blob”)。但是可以在文件生成之前提出请求。它肯定在以后可用。

服务器中有一个生成所有 blob 的批处理过程。项目 1234 已经存在,并且它的数据(而不是 blob)已经可用。服务器还没有生成 1234 的 blob。

我不想返回 404;那是为了不存在的东西。这将存在,但尚未生成。有点像正在“处理”的 YouTube 视频。我认为重定向代码也不合适;没有“其他”网址可以尝试。

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

首先,如果 thingy 1234 还没有任何 GET-able 表示,它在什么意义上作为资源存在(从客户端的角度来看)?事实上,在服务器内部有一个队列作业来创建 1234,这似乎并不意味着资源 1234 存在。其次,客户端从哪里获得 URI .../thingyblob/1234?在资源实际上可以获取之前,服务器可能不应该向客户端提供该 URI。
除了 blob 之外,thingy 还有其他值得获得的属性。只有blob需要时间来生成。客户通过例如 server/thingyapi/thingy/1234 获取这些
204“无内容”怎么样? Is 表示服务器已经成功处理了请求并且没有返回任何内容[此时]。

m
matsev

我建议202 - Accepted。从 documentation

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


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

这样的“问题”在服务器端:客户端发出了格式良好的请求,但服务器不能满足它。所以我倾向于“服务器错误”,5xx 状态码。

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

5xx(服务器错误)类状态码表示服务器知道它出错或无法执行请求的方法。除了响应 HEAD 请求时,服务器应该发送一个包含错误情况解释的表示,以及它是暂时的还是永久的条件。

笔记

“错误或无法执行请求”:尽管它们的标题是“服务器错误”,但它们不仅仅针对服务器错误。

“临时或永久”:这些代码适用于暂时不可用的资源,例如您的资源。

在可用的代码中,我会说 503, "Service Unavailable" 是最合适的:

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

笔记:

“经过一段时间的延迟可能会得到缓解”:对于您的情况是正确的。

“临时超载”:对您的情况而言并非迂腐正确。但是,可以说,如果您的服务器快得多,那么当客户端发出请求时,批处理就已经完成了,所以这是一种“过载”:客户端请求资源的速度比服务器可以做出的更快它们可用。

重试适合您的服务,因此您的回复应包含 Retry-After 值。您可以提供批处理的下一次执行的估计完成时间或批处理的执行间隔作为值。

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

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

客户会将您自己的状态代码视为 500, "Internal Server Error",这是不对的。


我看不出它比 202 好多少:benramsey.com/blog/2008/04/…
@JCCyC 您的博客为响应创建内容(POST 或 PUT)的请求返回 202 提供了一个很好的案例。这个问题似乎是在询问 GET 返回什么。
@JCCyC 它可以被视为一种不同的未就绪状态:想象一个对该资源的 ajax,您更喜欢 202 作为成功状态还是 503 作为错误状态?因此,您可以在应用对响应的反应的上下文中隐含地看到您更喜欢哪种含义
注意:“Retry-After”也可以与 307 - TEMPORARY REDIRECT 一起使用,如果您想在资源“准备好”时强制客户端在其他地方等待,这很好
这不是服务器的问题。不应使用 5xx 代码。用例是系统的预期和有效状态。部分生成的记录与部分功能的服务器不同。客户端也没有问题。他们要求在某个时候存在的有效资源。不应使用 4xx 代码。服务器的响应应该是“好的,但我仍在处理它”(202 接受)。
F
Fernando Ortega

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

423 (Locked) 状态码表示方法的源或目标资源被锁定。此响应应包含适当的前置条件或后置条件代码,例如“lock-token-submitted”或“no-conflicting-lock”。


优秀的答案!我想知道为什么它没有更多的赞成票。
也许是因为它是一个 WebDAV HTTP 代码?
从 akka-http 有 StatusCode RetryWith = reg(c(449)("Retry With", "The request should be retryed after doing the proper action.")) 其中的动作是等待并重试
在很多方面我都同意这一点。我有类似的情况(在我的情况下,从可能尚未填充的索引中搜索)。从语义上讲,我认为这是正确的。然而,423 的 RFC 声明“此响应应该包含适当的前置条件或后置条件代码,例如 'lock-token-submitted' 或 'no-conflicting-lock'。”不知道如何在这里应用。就个人而言,我会选择 409 Conflict,但没有评论就被否决了——不知道为什么?
@Adam 从状态名称中可以清楚地看出,仅当请求数据与服务器上可用数据的版本冲突时才应使用它。难怪到处都表明这种状态的最典型用例是无关的 PUT 请求。例如,尝试使用不再相关的数据更新某些资源(更新版本的数据已由先前的请求之一写入)
f
funroll

我不想返回 404;那是为了不存在的东西。

该 URL 与对事物的请求不对应。

http://server/thingyapi/thingyblob/1234

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

404。


我很高兴有人这么说!我不敢相信有这么多人认为 503 是适当的回应。更不用说其他一些奇怪的建议了。
尽管我同意 404 是这里最合适的响应,但它并没有回答 OP 的问题,即如何指示事物何时可用:-)。我认为 Retry-After 字段似乎是最好的候选者,但它只能正式用于 503 和 3xx 代码。 @Jason:我认为这解释了一些奇怪的建议。
我认为这是最好的答案。您可以在 404 响应中返回正文。身体可能会表明该东西将在以后提供。或者也使用 Retry-After 标头。该标准需要在这里扩展一点,因为它不能很好地涵盖这种情况。
人们已经太习惯于 404 意味着页面未找到,当在 API 的上下文中他们无法从逻辑上分离它。
这是sooooo 404。Thingyblob 还不存在,或者永远不存在。对于http,它是否可用是无关紧要的。目前它不存在,它的 404。它什么时候可用是另一个问题,可以通过从服务器向客户端推送消息来解决,比如 thingyblob:1234 可用。再次执行获取,瞧..
B
Brian Kelly

另一个选项:503 - Service Unavailable


According to W3C这不是你想对客户说的(尽管它在某种意义上意味着“再来一次”):“由于服务器临时过载或维护,服务器当前无法处理请求。暗示是这是一个暂时的情况,会在一些延迟后得到缓解。如果知道,延迟的长度可以在 Retry-After 标头中指示。如果没有给出 Retry-After,客户端应该像处理响应一样处理响应500响应。”
服务不可用,服务可用但处理未完成。所以503可能不是一个好主意。
s
skalee

由于您的资源尚未准备好,您可能知道(大约)它何时可用以及客户何时可以重试他的请求。这意味着您可能想要使用 Retry-After header。此标头对 503(服务不可用)有效,这意味着整个站点因维护而停机,以及 3xx(重定向)响应。

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


即使允许,如果客户端没有实现对 Retry-After 标头的支持,那么到同一页面的 3xx 重定向最终可能会以 503 结束...(当然可以选择使用 Retry-After 标头)
Retry-After 也适用于 RFC 6585(2012 年 4 月)添加的 HTTP 429“Too Many Requests”。如果资源尚未准备好的原因是客户端给服务器太多工作要做,这可能是合适的。
J
J Moore

409 冲突

表示由于请求中的冲突而无法处理请求,例如多次更新时的编辑冲突。 [来源维基百科。]

这可能是适当的。

如果您无法通过返回数据来满足请求 - 那么它就不会成功。我认为 202 表明服务器已将请求排队,稍后将完成请求。但是在您的情况下,请求现在是针对数据的并且失败了。如果您稍后重试,这是一个不同的请求。

我认为你有冲突..你想要数据..但它正在编辑/更新。如果 Thingy1234 已经存在并且之前已成功下载,但现在正在编辑的过程中在编辑进行时不可用,也会出现这种情况。


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

501 - 未实施

就像它的声音一样。尚未实现但暗示未来可用性的功能。

这是指向 summary of 5xx errors 的链接。


对于这个问题,听起来该功能本身存在,但所请求的项目不存在。
@Luke 501 在我的回答中的链接中的描述,'......它缺乏满足请求的能力。通常这意味着未来的可用性'。这完全满足了 OP 的要求。无论数据是否存在于他的服务器或数据库中。最终结果是目前无法通过 API 访问它。因此 API 无法满足请求,但想暗示它将在未来通过 http 代码提供。