对异步操作使用 http 状态202

我正在为一个接受用户提供的数据的服务编写 REST API。我希望保持所有操作完全异步,这包括 PUT、 POST、 DELETE 甚至 GET 请求。我的想法是接收请求,对请求进行足够的处理,以确保它是一个有效的请求,然后传递一个 HTTP 202接受的响应,以及一个最终可用数据的 URL 和一个令牌,以便后续请求可以与处理过的数据匹配。如果请求无效,那么我将发送一个 HTTP 400。

然后,客户机将负责检查我在将来某个时候提供给他们的 URL,并传递令牌。如果数据可用,我返回一个正常的200或201,但如果我仍在处理请求,我将发送另一个202,表明处理尚未完成。如果错误处理的数据,我将发送4xx 或5xx 状态作为必要的。

我想这样做的原因是,我可以将所有有效的请求转储到一个请求池中,并让工作人员从队列中拉出请求,并在请求可用时处理它们。由于我不知道池的大小或可用的工作人员的数量,我不能确定我可以得到足够快的请求,以满足30秒的谷歌应用程序引擎的限制。

我的问题是: 我是否以这种方式处理请求从而妨碍了 REST?例如,浏览器似乎要求对请求立即作出响应。对于我的 HTML 页面,我计划使用结构化页面进行响应,然后使用 AJAX 来处理数据请求。

我最感兴趣的是以这种方式使用 REST 处理数据的任何意见或经验。

36341 次浏览

我认为你的解决方案是好的,Http status 202正确的反应使用在这个特定的情况下,表明 请求已被接受处理,但处理尚未完成

我想在您的工作流程中稍微改变的是后续请求的 Http status

正如您所说的,202 response应该返回一个 Location header,指定客户端应该用来监视其以前请求的状态的 URL。
调用这个 检查进程状态 URL,而不是在进程挂起的情况下返回202,我将返回:

  1. 当请求的进程仍然处于待处理状态时,响应应该描述该进程的待处理状态。
  2. 处理完成后的 201 Created。GET/PUT/POST 情况下的响应应该包含请求/创建/更新资源的 Location。

对一个老问题补充一下我的看法,我的想法与 sympuntoout 和 Avi Flax 的建议相似。

我同意,对于通过 Location头重定向到另一个资源的初始请求,HTTP 202响应是合适的。

我认为 Location URL 应该包含您引用的令牌,以符合 Location重定向的一般期望。例如 Location: /queue?token={unique_token}Location: /task/{unique_token}

我还认为用于检查进程状态的资源应该在“检查状态”的操作成功时返回 HTTP 200响应(而不是 HTTP 202,因为这意味着当前请求已被“接受”)。

但是,我认为在创建新实体时,“检查状态”应该在新实体创建后返回带有 Location头的 HTTP 303(去见其他人)响应。这比发送 HTTP 201更合适,因为由于刚刚执行了检查状态的 GET请求,没有创建任何东西。

我还认为用于检查状态的资源应该适当地返回错误代码。无论何时成功执行“检查状态”,都应该返回适当的成功代码。可以在应用程序级别处理错误(通过检查响应主体)。

这是一个非常古老的问题,但我想提出一个稍微不同的看法,我不声称是正确的,只是我的看法。

从客户的角度来看

让我们从最初的 HTTP 请求开始。首先,请求应该是 POST。您正在向服务器发送消息以创建资源。GET 和 PUT 在本例中无效,因为:

  • GET 在此上下文中无效,因为 GET 意味着在特定位置获取资源
  • PUT 无效,因为您没有创建请求,而是要求服务器创建请求。

从服务的角度来看

因此,现在要向服务器发送 POST 来处理请求。服务器实际上有3个可能的返回值(不包括4xx 和5xx 错误) :

  • “201Created”表示服务获得了请求并能够立即处理它,或者在可接受的时间段内处理它。这个时间段完全取决于服务设计。这由服务开发人员来定义。
  • “202Accepted”表示服务获得了请求并正在处理它。当服务知道某些事情需要一段时间才能完成时,就会使用这种方法。另一种观点是,如果服务依赖于任何其他异步操作,而它无法确定结果,那么它应该返回“202 Accepted”响应。最后,一些服务设计人员可能只是简单地返回“202Accepted”,而不管它能以多快的速度完成。
  • 在某些情况下,你会得到一个“302发现”。这通常是当服务可以将请求标识为生成已经存在(并且仍然有效且不处于错误状态)的资源,并且可以重用现有资源时。并非所有的服务都是这样工作的: 向线程发布评论应该总是创建新的资源。其他服务也是这样做的: 发布一系列标准,获得一份医生名单,产生相同的医生名单。如果这些信息可以重用,那么就重用它们。
  • 对于所有这些响应,“ Location”HTTP Header 返回到包含可以找到资源的客户端。这一点很重要,正如您稍后将看到的那样,有些人往往在方法上有分歧。如果资源可以与其他请求一起重用,那么“ Location”的生成方式应该是相同的请求总是生成相同的 URL。这提供了大量的缓存和重用。

当服务成功完成请求时,它将在返回给客户端的位置创建资源。

现在我开始看到与上面的反应有点不同的东西。

如果服务未能完成请求,它仍应在返回给客户端的位置创建资源。此资源应指示失败的原因。让资源提供故障信息比试图将其塞入 HTTP 协议要灵活得多。

如果服务在完成之前获得对此资源的请求,它应该返回“404 Not Found”。我之所以认为它应该是“404未找到”,是因为它实际上并不存在。HTTP 规范并没有说“404 Not Found”只能在资源永远不存在的情况下使用,只是说它现在不存在。在我看来,这种对异步轮询流的响应类型是完全正确的。

还有一种情况是,资源应该只在一个固定的时间内存在。例如,它可能是基于每晚刷新的源的数据。在这些情况下,应该删除资源,但是应该向服务提供一个指示器,它可以知道返回一个“410 Gone”状态代码。这基本上是告诉客户端资源在这里,但不再可用(即: 可能已过期)。来自客户端的典型操作是重新提交请求。

从客户的角度来看

当客户端获得初始 POST 的响应时,它获得“ Location”并使用该 URL 使用 GET (同样,不是 POST)向服务发出请求。服务通常会以下列值作出响应:

  • “200 OK”表示请求已完成。请求的结果在内容体中返回,提供由 Accept HTTP 头定义的格式的内容。
  • “404未找到”将告诉客户端请求尚未完成,资源尚未到达,在这种情况下,它基本上应该稍后再试一次。
  • 如果客户端在很长一段时间后试图获取资源,但资源已经不存在了,那么“410 Gone”将被返回。在这种情况下,它只需重新提交原始查询

需要指出的一点是,返回的资源通常采用能够定义成功和失败响应的格式。客户端应该能够从这个资源中确定是否存在错误,它是什么,并能够相应地做出响应。

此外,服务开发人员可以使服务在短时间内过期并删除错误资源。

这就是我对这个问题的看法。现在已经很晚了,但希望未来的读者会对一个常见的问题有稍微不同的看法。

FWIW,MicrosoftFlow 使用这样的模式。
第一个调用返回202w/Location 头。 后续电话回复: 1.如果仍在处理—— > 202 w/a 位置头。Loc 头可以不同,它提供了在调用之间传递状态的方法(并可能使服务器无状态!). 2. 如果完成—— > 200。

详情请浏览: https://github.com/jeffhollan/LogicAppsAsyncResponseSample