java - REST - POST 到资源集合和 If-Match header 时的 ETag

每个用户都有一个 gem Collection 。可以通过 REST API 访问这些 gem:

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) gem ,但这对我的问题并不重要。实际上,它很重要。请继续阅读。)

从高层次的角度来看,他们做了以下事情:

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

如前所述,这些进程并行运行。通常,两个进程不管理同一用户的 gem,但这种情况可能会发生。

所以我需要一种机制来禁止在步骤 3b 中的 POST 如果同时发生某些事情。我考虑过使用 ETag 和乐观锁定:

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

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

最佳答案

当然,您的问题听起来非常适合 ETag 的使用。它是一个集合这一事实并不重要;重要的是它是一种具有表示的资源,您可以从中始终如一地生成 ETag。

要考虑的一件事是,集合的表示是否有任何可以更改的内容,而这对您的 API 使用者来说并不重要。例如,假设您以某种随机或不一致的顺序输出集合,但集合在语义上定义为无序。在那种情况下,您可以生成 weak ETag基于集合中的项目集。

关于java - REST - POST 到资源集合和 If-Match header 时的 ETag,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38843625/

相关文章:

reactjs - 每个 child 在 React 中应该有一个唯一的关键错误

c# - 使用 Entity Framework 定义关系/FK 的两端是否重要?

python - 在 Python 中查找对称矩阵的 SVD

c# - app.config 的困境 - 为什么我不能嵌入应用程序配置?

f# - 使用寓言中的节点模块

r - 如何在 R 中创建边际效应表?

java - 从另一个项目注入(inject) FeignClient 时出错

c# - WCF 服务在多服务器环境中不起作用

python - 查找文本是否突出显示

android - 键盘打开android时布局正在缩小