RFC 6902很明确地定义了很多东西。除了两个相关的事情:
例如
GET /news/123
[
{"title": "Hello", "contents": "World", "categories": [1, 2, 3]}
]
结果来自这些数据库表和列:
title = news.title
contents = news.contents
categories = newscategories_mapping WHERE newscategories_mapping.newsID = news.id
所以,如果我发送补丁:
PATCH /news/123
[
{"op": "replace", "path": "/title", "value": "New Title"}
]
非常简单。但是当我想要更新同一资源的类别时呢? IE浏览器。 "加入"表
PATCH /news/123
[
{"op": "replace", "path": "/categories", "value": [4, 5]}
]
另外,请注意两件事:
让我们说补丁之前的原始值是newscategories_mapping.id
20,21和22。
问题1:新/categories
值4
是否会替换id = 20,值5
是否会替换id = 21?或者应该删除id = 20,id = 21和id = 22并且新值获取新ID id = 23且id = 24?
问题2:是否应删除id = 22,即使未明确请求?
问题3:或者根本不应该完成上述操作,而我应该使用单独的端点来修补每个类别?所以,例如。 PATCH /news/123/categories/20
和PATCH /news/123/categories/21
?
答案 0 :(得分:0)
您可以为您的请求添加多个JSON Patch细分。要么所有步骤都应用,要么根本不应用,所以在事务中应用它们!
PATCH /news/123
[
{"op": "replace", "path": "/title", "value": "New Title"},
{"op": "replace", "path": "/categories", "value": [4, 5]}
]
问题1:新/类别值4应该替换id = 20,值5是否替换id = 21?或者应该删除id = 20,id = 21和id = 22并且新值获取新ID id = 23且id = 24?
RFC状态明确The "replace" operation replaces the value at the target location with a new value.
因此,应用补丁后的值应为4和5.您基本上用补丁操作中给出的列表替换现有列表。
问题2 :即使未明确请求,也应删除id = 22?
是
问题3 :或者根本不应该完成上述操作,而我应该有一个单独的端点来修补每个类别?所以,例如。 PATCH / news / 123 / categories / 20和PATCH / news / 123 / categories / 21?
补丁是由客户端计算的简单指令,服务器应将其执行以将目标资源转换为预期结果。如果要在categories
元素的最终状态中包含22,则有两个选项:
replace
操作中发送的值中的旧值添加到要设置的列表中add
操作,您可以在删除其他值后明确添加所需值客户端应始终在发送补丁请求之前从服务器检索最新状态。通常,修改应该应用于最新状态,因此ETag标头用于利用乐观锁定并防止更新过时状态。