我正在设计一个ReST https://restfulapi.net/遵循基本的APICRUD https://en.wikipedia.org/wiki/Create,_read,_update_and_delete图案。
我的 API 可以接收更新资源的请求,该请求可能需要很短的时间来处理。理想情况下,我想通知客户新版本即将推出,并且我缓存的版本何时实际过期存在一些不确定性。
所以我打算使用这样的过程(欢迎改进):
client: GET /some/item
myapi: 200 OK
last-modified: time-stamp-of-v1
etag: some-hash-relating-to-v1-of-my-item-in-this-format
content: json or whatever
data/for/some/item/v1...
client: PUT /some/item
if-match: some-hash-relating-to-v1-of-my-item-in-this-format
content: json or whatever
data/for/some/item/v2...
myapi: 202 ACCEPTED,
content: json or whatever
time-accepted: time-stamp-after-v1-but-before-v2
your item will be at /some/item
here is a URI /some/taskid to track progress
当上传等待时:
client: GET /some/item
myapi: 200 OK
some/item ...
last-modified: time-stamp-of-v1
etag: some-hash-relating-to-v1-of-my-item-in-this-format
>>>> expires: time-stamp-after-v1-but-before-v2 <<<
>>>> warning: 110 Response is stale <<<<
content: json or whatever
data/for/some/item/v1...
client: GET /some/task/id
myapi: 200 OK
content: json or whatever
time-accepted: time-stamp-after-v1-but-before-v2
your item will be at /some/item
status/of/upload/v2...
任务完成后:
client: GET /some/item
myapi: 200 OKAY
some/item/v2 ...
last-modified: time-stamp-of-v2
etag: some-hash-relating-to-v2-of-my-item-in-this-format
content: json or whatever
data/for/some/item/v2...
client: GET /some/task/id
myapi: 303 SEE OTHER
look-here: /some/item
如果您是代理并且知道您的内容已过时,您可以在标头中添加“警告:110 - 响应已过时”。
然而,在这种情况下,数据实际上还不是无效的。
我想说的是,我可以保证它在我收到并传递上传请求之前一直有效(v1 之后但 v2 之前的时间戳或稍后,就像我与上传服务器联系一样)。当我收到上传请求时,它还没有真正过期。我只是期待它会发生。
(事实上,如果请求失败,它可能根本不会更新)。
现在,默认选择只是提供旧内容并让客户端自行赶上。这具有高延迟。如果可以的话,我想做得更好。
例如,如果客户端知道文档即将过期,它可以更频繁地轮询,或者可以尝试升级到 Web 套接字的连接,并在我收到它时立即发送更新(这仍然算作 ReST 吗?)
还有另一种情况,必须不惜一切代价避免使用过期数据。对于这种情况,我想我想告诉客户端资源暂时不可用。像我上面那样使用警告和过期字段似乎是正确的。不过,发送带有合适的重试后标头的 503 可能会更好。
所以问题是:当新版本上传待处理时,我应该如何回复 GET?
考虑到使用 AMQP 或 ZeroMQ 等消息传递框架来实现低延迟的答案,我应该指出,此 API 充当不愿意直接使用 AMQP 的客户端的 AMQP 网关/代理。有关使用 webhook 或 websocket 的信息仍然很有趣。
一些相关的有用内容是:
- 如何正确设计一个 Restful API 来使缓存失效? https://stackoverflow.com/questions/13291805/how-to-proper-design-a-restful-api-to-invalidate-a-cache
- https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
- 暂时不可用页面的 HTTP 状态代码 https://stackoverflow.com/questions/4642923/http-status-code-for-temporarily-unavailable-pages
-
http://www.albertoleal.me/posts/how-to-prevent-race-conditions-in-restful-apis.html http://www.albertoleal.me/posts/how-to-prevent-race-conditions-in-restful-apis.html(etag 阻止比赛同时上传)