REST-当向资源集合POST时使用ETag和If-Match头部信息

3

每个用户都有一组宝石。这些宝石可以通过 REST API 访问:

GET    /user/<user id>/gem              -> get all gems
GET    /user/<user id>/gem/<gem id>     -> get an existing gem
POST   /user/<user id>/gem              -> add a new gem
PUT    /user/<user id>/gem/<gem id>     -> edit an existing gem
DELETE /user/<user id>/gem/<gem id>     -> delete an existing gem

我有几个后端进程,它们同时运行,并可以通过POST HTTP方法添加gem。 (它们也可以编辑(PUT)或删除(DELETE)gems,但这对我的问题不重要。实际上,它很重要。请继续阅读。)
从高层次来看,它们执行以下操作:
1.  GET /user/<current user id>/gem
2.  some calculations, based on step 1
3a. if (step 2 decided that a gem should be added)
3b.     POST /user/<current user id>/gem

正如所说,这些进程并行运行。通常情况下,两个进程不会管理同一用户的宝石,但也可能发生。
因此,如果在此期间有任何更改,我需要一个机制来禁止步骤3b中的POST。 我考虑使用ETags和乐观锁定:
1.  GET /user/<current user id>/gem and remember the returned ETag
2.  some calculations, based on step 1
3a. if (step 2 decided that a gem should be added)
3b.     POST /user/<current user id>/gem with header 'If-Match=<ETag from step 1>'
3c.     if (server returns 412 - precondition failed)
3d.         start again at step 1

我不确定ETags是否适用于此。大多数ETag的示例都只涉及单个资源(例如/gem/23),而不是一组资源(例如/gem)。也就是说,在步骤3b中,我提供了完整宝石集合的ETag,而实际上我只提供一个要添加的宝石。

1个回答

0

没问题,你的问题似乎非常适合使用ETags。事实上,它是一个集合并不重要;重要的是它是一个资源,可以从中生成一致的ETag。

需要考虑的一个问题是,如果集合的表示中有任何与API使用者无关的变化。例如,假设您以某种随机或不一致的顺序输出集合,但该集合在语义上被定义为无序。在这种情况下,您可以基于集合中的项目集生成弱ETag


谢谢你提醒在这里使用弱 ETag! - Theodore Jeeves

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接