资源 ID 应该放在 PUT 和 PATCH 请求的 URL 中吗?
Should the resource ID be put in URL of PUT and PATCH requests?
PUT 和 PATCH 的 URL 应该包含 ID 还是可以放在正文中?
PUT /person/UUID {"name": "Jimmy"}
或
PUT /person/{"UUID":1, "name": "Jimmy"}
(补丁相同)
?
因为 PUT
被定义为 将在 URI 位置找到的当前文档替换为有效载荷中提供的文档 发送一个 PUT
请求到 /person
可能会导致删除由该特定端点管理的任何人,以防 URI 代表一组人。
如 中所述,如果这是一个通用容器,可能会使用不带某些特殊实体标识符的 URI。想象一个剪贴板,您可以在其中复制一些数据,以便稍后检索它以将其粘贴到其他地方。在这种情况下,标识符由 URI 本身隐式给出,因为毕竟 URI 代表 唯一资源标识符
请注意,URI 作为一个整体标识资源,并不一定意味着某种形式的父子结构。客户端尤其不应尝试从 URI 中提取知识。
关于 PATCH
视情况而定。通常应该使用一种用于修补的媒体类型,例如 JSON Patch or JSON Merge Patch.
前一种表示定义了某些字段,这些字段声明应添加、删除或替换为给定值的字段,如下所示:
PATCH /my/data HTTP/1.1
Host: example.org
Content-Length: 326
Content-Type: application/json-patch+json
If-Match: "abc123"
[
{ "op": "test", "path": "/a/b/c", "value": "foo" },
{ "op": "remove", "path": "/a/b/c" },
{ "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] },
{ "op": "replace", "path": "/a/b/c", "value": 42 },
{ "op": "move", "from": "/a/b/c", "path": "/a/b/d" },
{ "op": "copy", "from": "/a/b/d", "path": "/a/b/e" }
]
JSON 合并补丁的工作方式不同。它定义了一些默认规则,这些规则指示服务器如何将更改应用到目标文档。如下所示的文档,即添加或更新字段 a 以在 属性 f 之后具有值 z必须删除 c 的对象的 。该资源的所有其他剩余属性保持原样。
PATCH /target HTTP/1.1
Host: example.org
Content-Type: application/merge-patch+json
{
"a":"z",
"c": {
"f": null
}
}
这两种媒体类型都可以用来直接向“集合”资源发送请求,因为根据定义,它们都可以定位子元素。但是,就缓存而言,我会尽量避免它。
HTTP 中的缓存实际上作用于资源的 URI。对该 URI 执行的任何不安全操作都会导致缓存使该目标的存储表示无效。 IE。如果您之前调用 GET /person/1
现在执行 PUT
或 PATCH
,这两者都是不安全的操作,在 /person
上数据可能会更新,尽管客户端请求 GET /person/1
之后仍然可以通过缓存检索缓存的响应,因为它不知道对该资源所做的任何更改。
PUT 和 PATCH 的 URL 应该包含 ID 还是可以放在正文中?
PUT /person/UUID {"name": "Jimmy"}
或
PUT /person/{"UUID":1, "name": "Jimmy"}
(补丁相同) ?
因为 PUT
被定义为 将在 URI 位置找到的当前文档替换为有效载荷中提供的文档 发送一个 PUT
请求到 /person
可能会导致删除由该特定端点管理的任何人,以防 URI 代表一组人。
如
请注意,URI 作为一个整体标识资源,并不一定意味着某种形式的父子结构。客户端尤其不应尝试从 URI 中提取知识。
关于 PATCH
视情况而定。通常应该使用一种用于修补的媒体类型,例如 JSON Patch or JSON Merge Patch.
前一种表示定义了某些字段,这些字段声明应添加、删除或替换为给定值的字段,如下所示:
PATCH /my/data HTTP/1.1
Host: example.org
Content-Length: 326
Content-Type: application/json-patch+json
If-Match: "abc123"
[
{ "op": "test", "path": "/a/b/c", "value": "foo" },
{ "op": "remove", "path": "/a/b/c" },
{ "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] },
{ "op": "replace", "path": "/a/b/c", "value": 42 },
{ "op": "move", "from": "/a/b/c", "path": "/a/b/d" },
{ "op": "copy", "from": "/a/b/d", "path": "/a/b/e" }
]
JSON 合并补丁的工作方式不同。它定义了一些默认规则,这些规则指示服务器如何将更改应用到目标文档。如下所示的文档,即添加或更新字段 a 以在 属性 f 之后具有值 z必须删除 c 的对象的 。该资源的所有其他剩余属性保持原样。
PATCH /target HTTP/1.1
Host: example.org
Content-Type: application/merge-patch+json
{
"a":"z",
"c": {
"f": null
}
}
这两种媒体类型都可以用来直接向“集合”资源发送请求,因为根据定义,它们都可以定位子元素。但是,就缓存而言,我会尽量避免它。
HTTP 中的缓存实际上作用于资源的 URI。对该 URI 执行的任何不安全操作都会导致缓存使该目标的存储表示无效。 IE。如果您之前调用 GET /person/1
现在执行 PUT
或 PATCH
,这两者都是不安全的操作,在 /person
上数据可能会更新,尽管客户端请求 GET /person/1
之后仍然可以通过缓存检索缓存的响应,因为它不知道对该资源所做的任何更改。