我们的团队目前正在进行讨论,我对其他观点感兴趣。假设我们有一个RESTful Web服务,其作用是通过应用各种分析算法和服务来注释文档。明确的基本交互:我们有一个资源,即文档集合;客户端将新文档发布到集合,获取新文档的URI,然后获取docURI
以获取文档或获取{docURI}/metadata
以查看常规元数据{{1}对于命名实体等,问题是某些分析可能需要很长时间才能完成。假设客户端在分析完成之前获取元数据URI,因为它希望能够在UI中显示部分或增量结果。将来重复GET可能会产生更多结果。
我们讨论的解决方案包括:
{docURI}/ne
和content-length
标题来获取增量内容(但是
我们事先不知道多久
最终内容将是)有关在RESTful架构中处理长期或异步交互的替代方法的任何意见或建议吗?
伊恩
答案 0 :(得分:3)
我会用以下方式实现它:
1)客户请求元数据
2)服务器返回实际数据(如果已经可用)或NotReady标记
3)客户端询问服务器何时可以获得数据(此步骤可以与之前合并)
4)服务器返回时间间隔(执行作业总数可能有一些启发式等)
5)客户等待指定的时间段并转到步骤1
这样您就可以尽快向客户提供数据。您可以通过调整在步骤4)返回的延迟间隔来调整服务器负载
答案 1 :(得分:3)
为每个资源提供一个Atom提要,以便客户端订阅更新事件而不是简单地获取资源(如果有许多活动文档,似乎过于复杂并且可能资源很耗尽)
您考虑过SUP吗?
如果轮询是一种选择,为什么还要费心?为什么不让客户端轮询资源本身?
你能否通过计算完成分析的预计时间来减少不必要的民意调查?
答案 2 :(得分:2)
另外,请查看RESTful Web Services - 这是我了解上述内容的地方。
答案 3 :(得分:2)
- 只是忽略幂等性并让GET返回当时可用的东西(但它仍然留下了客户知道我们什么时候最终完成的问题)。
随着时间的推移,返回不同结果的GET是否真的意味着它不是幂等的? The spec说:
方法也可以具有“幂等性”的特性(除了错误或期满问题之外)N的副作用> 0个相同的请求与单个请求相同
也就是说,多次调用GET可能会返回不同的结果,只要调用本身没有副作用。
在这种情况下,也许您的REST方法可以使用条件GET和缓存机制来指示何时完成:
GET {docURI}/metadata
响应可能会:
Expires
标头设置为几秒钟。ETag
标题。Expires
标题。ETag
。使用ETag
的后续请求应返回304 Not Modified
。注意,您可能需要考虑缓存中涉及的其他响应头,而不仅仅是Expires。
这种“感觉”就像一个RESTful设计 - 你可以想象一个网页浏览器做正确的事情,因为它连续请求这个资源。
答案 4 :(得分:1)
“只是让GET返回当时可用的任何东西”,这很有意义。除了在他们进行投票时,你不想继续他们已经知道的东西。每次轮询时答案都会变长。
你需要他们在GET请求中为你提供他们“迄今为止所看到的”。这为您提供了幂等性。如果他们要求大块1,他们总能得到相同的答案。一旦他们看到大块1,他们就可以要求大块2。
答案并没有变得更大。更多件可用。 “集合级”GET提供响应的大小。您可以获得每件可用的“详细级别”GET。
基本上,这是一种类似于TCP / IP确认的算法。当他们说一件时,你发送下一件。如果有下一篇文章,否则你发送一个200-nothing new报告。
客户知道我们何时终于完成的问题是无法估量的。他们无法知道,你无法预测需要多长时间。
你不希望他们“忙着等待” - 轮询看你是否已经完成 - 这对你的服务器来说是一个相当大的负担。如果他们不耐烦。你可以限制他们的请求。您可以向他们发送“在x秒内检查”,其中x逐渐变大。
你甚至可以使用Unix风格的调度算法,当他们轮询时他们的分数下降,如果他们不轮询X秒,他们的分数就会下降。
替代方案是某种队列,您可以将结果发回给他们。 要做到这一点,他们必须提供一个你可以POST的URI告诉他们你已经完成了。
或者,他们使用Atom来实现轻量级轮询架构。虽然Atom看起来很复杂 - 它仍然涉及轮询 - 你提供了一个最小的Atom答案(“还没有改变”)直到你完成,当你提供(“新结果”)所以他们可以做真实重量级得到。这是全有或全无的,而不是上面的增量响应技术。
您也可以将“集合级别”GET视为整个流程的Atom状态。
答案 5 :(得分:1)
在您的情况下可能适合或不适合的一种替代解决方案是添加名为“AnnotationRequests”的新端点。将文档(或其链接)发布到AnnotationRequests端点,它应返回一个位置(例如http://example.org/AnnotationRequest/2042),以允许您的客户端轮询该过程的状态。当该过程完成时,“AnnotationRequest”表示可以包含指向已完成文档的链接。
这样做的一个不错的副作用是您可以对AnnotationRequests执行GET,因此请查看当前正在处理的文档。由您决定要保留AnnotationRequests的时间。保留完整的历史记录可能是有价值的,这些历史记录了它们被请求的时间,每个人服用的时间和持续时间,或者可以定期将它们丢弃。
答案 6 :(得分:1)
您可以查看Udi Dahan's nServiceBus。