作为REST服务的一部分,我需要实现搜索调用。基本思想是用户可以发布新搜索,并获得结果:
POST http://localhost/api/search
GET http://localhost/api/search?id=123
但是,我的搜索可能会运行几分钟,并返回部分结果,直到完成为止。也就是说,GET-Request会返回类似的内容:
status: running
results: a, b, c.
而下一个GET-Request可能会返回
status: completed
results: a, b, c, d, e.
这与RESTful GET请求的语义相矛盾。多次调用时,请求应始终返回相同的结果。例如,当用户使用高速缓存代理时,可能永远不会将完整结果传递给用户。
问题:有没有办法为部分结果的长时间运行搜索提供真正的RESTful实现?
答案 0 :(得分:31)
在执行搜索时,您可以设置相应的响应标头(例如Expires
或max-age
)以指示不应缓存响应(HTTP / 1.1 14.9.3,{ {3}})。
搜索结果完成后,您可以发送更合适的Expires
/ max-age
标头,以允许或扩展结果的可缓存性。
客户端负担重新查询资源,直到其搜索状态完成。客户端可以使用Expires头的值来确定何时应该重新查询更新的结果。
除此之外,您还可以 使用自定义2XX状态代码来指示结果尚未完成。也许是HTTP/1.1 299 In Progress
或其他任何有意义的东西。规范表明HTTP状态代码为13.4。
为了记录,你的陈述:
对于GET请求,这与RESTful GET请求的语义相矛盾。多次调用时,请求应始终返回相同的结果。
不适用 - 资源可能会发生变化。 GET请求是幂等的只意味着“...... N> 0个相同请求的副作用与单个请求相同”。 are extensible
答案 1 :(得分:9)
几天前,我偶然发现了一篇关于你的问题的reddit博客文章。您可能需要查看它:Bill Higgin's RESTy long-ops。
快乐阅读。
答案 2 :(得分:2)
如果第一个GET请求返回部分结果,并且第二个GET请求返回完整结果,则不是问题。那是因为第一个GET请求不会导致第二个请求的结果发生变化:即使没有发出第一个GET,该请求也会返回完整的结果。 “幂等”并不意味着相同的结果。这意味着第一个GET不会影响第二个GET。
如果第一个GET请求返回部分结果,那将是一个问题,第二个GET将返回剩余的结果(第一个GET返回A,B,C;第二个GET返回D,E,F)。这里第一个GET改变了第二个结果,所以它不是RESTful。
答案 3 :(得分:0)
也许不是最优雅的答案,但会绕过缓存代理:只是不要发送两次相同的查询。为查询添加时间戳(&time=1318355458
)。这样,每个请求都是唯一的(如果您请求> 1hz,您还可以添加毫秒数)。
至于遵循“请求应该总是在多次调用时返回相同结果”的原则,对于在同一查询的不同时间返回部分结果的目标而言似乎在逻辑上是矛盾的。
答案 4 :(得分:0)
如果你只想要完整的结果,你可以等待而不是民意调查吗?
为什么你不能提供一个资源作为POST的一部分来获得结果PUT呢?您正在提供一个“回调”REST接口,因此客户端进程不是轮询,而是等待对所提供资源的PUT。然后,您可以获得结果,或者结果可以包含在PUT中。