我正在为接受用户贡献数据的服务编写REST API。我想保持所有操作完全异步,这包括PUT,POST,DELETE甚至GET请求。我的想法是接收请求,处理它以确保它是一个有效的请求,然后传递HTTP 202接受的响应以及数据最终可用的URL和令牌,以便后续请求可以与处理的数据匹配。如果请求无效,那么我将发送HTTP 400。
然后,客户将负责检查我在将来某个时间提供的URL并传递令牌。如果数据可用,我返回正常的200或201,但如果我仍在处理请求,我将发送另一个202,表明处理尚未完成。如果处理数据有误,我会根据需要发送4xx或5xx状态。
我想这样做的原因是我可以将所有有效请求转储到请求池中,让工作人员从队列中提取并处理请求,因为它们可用。由于我不知道池的大小或可用的工作人员数量,因此无法确定我能够以足够快的速度获得请求以满足Google App Engine的30秒限制。
我的问题是:我是否通过以这种方式处理请求来歪曲REST?例如,浏览器似乎需要立即响应请求。对于我的HTML页面,我计划使用结构化页面进行响应,然后使用AJAX处理数据请求。
我最感兴趣的是以这种方式使用REST处理数据的任何意见或经验。
答案 0 :(得分:36)
我认为您的解决方案很好,Http status 202
是在此特定情况下使用的proper response,表示请求已被接受处理,但处理尚未完成
我在工作流程中略微改变的是后续请求的Http status
。
正如您所说,202 response
应返回Location header
,指定客户端用于监控其先前请求状态的网址。
调用此检查我的进程状态 URL,而不是在进程挂起的情况下返回202,我会返回:
200 OK
当请求的进程仍处于待处理状态时。响应应描述该过程的待定状态。201 Created
。 GET / PUT / POST情况下的响应应包含所请求/创建/更新资源的位置。 答案 1 :(得分:25)
将我的两分钱加到旧问题上。我的想法类似于systempuntoout和Avi Flax的建议。
我同意HTTP 202
响应适用于初始请求,并通过Location
标头重定向到其他资源。
我认为Location
网址应该包含您引用的令牌,以符合Location
重定向的常见期望。例如Location: /queue?token={unique_token}
或Location: /task/{unique_token}
。
我还认为用于检查进程状态的资源应该在“检查状态”操作成功时返回HTTP 200
响应(不是HTTP 202
因为这意味着当前请求被“接受”)。
但是,我认为在创建新实体时“检查状态”应该返回HTTP 303
(See Other)响应,并在新实体生成后使用Location
标头创建。这比发送HTTP 201
更合适,因为由于刚刚执行GET
请求来检查状态而没有创建任何内容。
我还认为用于检查状态的资源应该适当地返回错误代码。只要成功执行“检查状态”,就应返回适当的成功代码。可以在应用程序级别处理错误(通过检查响应正文)。
答案 2 :(得分:6)
这是一个非常古老的问题,但我想提出一个略有不同的观点,我并不认为这是正确的,只是我的看法。
从客户的角度来看
让我们从初始HTTP请求开始。首先,请求应该是POST。您正在向服务器发送消息以创建资源。在这种情况下,GET和PUT无效,因为:
从服务角度
现在您正在向服务器发送POST以处理请求。服务器实际上有3个可能的返回值(不包括4xx和5xx错误):
当服务成功完成请求后,它将在返回给客户端的位置创建资源。
现在,我开始看到与上述反应略有不同的地方。
如果服务无法完成请求,它仍应在返回给客户端的位置创建资源。该资源应指出失败的原因。使资源提供故障信息比尝试将其变为HTTP协议更加灵活。
如果服务在完成之前获得对此资源的请求,则应返回" 404 Not Found"。我之所以认为它应该是'#404; 404 Not Found"是因为它确实不存在。 HTTP规范没有说" 404 Not Found"只能在资源永远不存在的情况下使用,只是它现在不存在。在我看来,这种对异步轮询流的响应是完全正确的。
还有一种情况是资源应该只存在一段固定的时间。例如,它可以是基于每晚刷新的源的数据。在这些情况下应该发生的事情是应该删除资源,但是应该向服务提供一个指示器,它可以知道返回一个" 410 Gone"状态代码。这基本上告诉客户端资源在这里,但不再可用(即:可能已经过期)。客户端的典型操作是重新提交请求。
再次从客户的角度来看
当客户端获得其初始POST的响应时,它会获得"位置"并使用GET(再次,不是POST)使用该URL向服务发出请求。该服务通常会响应这些值:
需要指出的一点是,返回的资源通常采用可定义成功和失败响应的格式。客户端应该能够从该资源中确定是否存在错误,错误是什么,并且能够做出相应的响应。
此外,服务开发人员可以使服务过期并在短时间内删除错误资源。
这就是我对这个问题的看法。这个聚会很晚,但希望未来的读者可能会看到一个与常见问题略有不同的观点。
答案 3 :(得分:1)
FWIW,Microsoft Flow使用这样的模式。
第一次调用返回202 w / Location标头。
跟进电话返回:
1.如果仍在处理 - > 202 w / a位置标题。 loc头可以是不同的,这提供了一种在调用之间传递状态的方法(并且可能使服务器无状态!)。
2.如果完成 - > 200.
详细信息:https://github.com/jeffhollan/LogicAppsAsyncResponseSample