我正在设计一个 Web 服务来定期接收列表更新。此时,列表仍然可以建模为单个实体 ( /lists/myList
) 或具有许多资源的实际集合 ( /lists/myList/entries/<ID>
)。列表很大(数百万个条目),更新很小(通常少于 10 次更改)。
客户端将获取要分发的 Web 服务 URL 和列表,例如:
- http://hostA/service/lists : list1, list2
- http://hostB/service/lists : list2, list3
- http://hostC/service/lists : list1, list3
然后它将按配置推送列表和更新。Web 服务 URL 后面是否有一些数据库很可能但尚未确定。
我一直在研究,似乎使用 JSON 补丁格式的 HTTP PATCH 是最好的方法。
背景和示例:每个列表都有一个识别名称、一个优先级和数百万个条目。每个条目都有一个 ID(由客户端确定)和几个可选属性。创建具有优先级 1 和两个列表条目的列表“requiredItems”的示例:
PUT /lists/requiredItems
Content-Type: application/json
{
"priority": 1,
"entries": {
"1": {
"color": "red",
"validUntil": "2016-06-29T08:45:00Z"
},
"2": {
"country": "US"
}
}
}
对于更新,客户端首先需要知道列表现在在服务器上的样子。为此,我将向列表实体添加一个属性“修订”。
然后,我会查询这个属性:
GET /lists/requiredItems?property=revision
然后客户端会看到服务器上的版本和客户端已知的最新版本之间需要更改的内容,并编写一个 JSON 补丁。例子:
PATCH /list/requiredItems
Content-Type: application/json-patch+json
[
{ "op": "test", "path": "revision", "value": 3 },
{ "op": "add", "path": "entries/3", "value": { "color": "blue" } },
{ "op": "remove", "path": "entries/1" },
{ "op": "remove", "path": "entries/2/country" },
{ "op": "add", "path": "entries/2/color", "value": "green" },
{ "op": "replace", "path": "revision", "value": 10 }
]
问题:
- 由于不经常使用的 HTTP 动词 PATCH,这种方法的缺点是客户端支持略少。在不牺牲 HTTP 兼容性(幂等性等)的情况下,是否有更兼容的方法?
- 将单个列表条目建模为单独的资源并使用
PUT
andDELETE
(可能与ETag
and/orIf-Match
)似乎是一种选择(PUT /lists/requiredItems/entries/3
,DELETE /lists/requiredItems/entries/1
PUT /lists/requiredItems/revision
),但是当网络落在更新链的中间时,我如何确保应用所有这些操作?HTTP PATCH 是否允许在多个资源上工作? - 有没有更好的方法来“版本”列表,也许隐含地也改进了它们的更新方式?请注意,客户端确定修订号。
- 用 查询修订号是否正确
GET /lists/requiredItems?property=revision
?它应该是一个单独的资源/lists/requiredItems/revision
吗?如果它应该是一个单独的资源,我将如何自动更新它(即列表和修订都更新或都没有更新)? - 它可以在 JSON 补丁中首先测试修订值
3
,然后将其更新到10
同一个补丁中吗?