PUT和PATCH的URL应该包含ID,还是可以放在正文中?
PUT /person/UUID {"name": "Jimmy"}
或者
PUT /person/{"UUID":1, "name": "Jimmy"}
(PATCH也一样)?
如 PUT
定义为 用有效载荷中提供的文档替换在URI位置找到的当前文档。 发送 PUT
请示 /person
可能会导致删除由该特定端点管理的任何人员,如果该URI代表一个人员集合的话。
正如在 此职位 我们可以使用一个没有特殊实体标识符的URI,以防这是一个通用的容器。想象一下剪贴板,你可以把一些数据复制到剪贴板上,然后再检索出来粘贴到其他地方。在这种情况下,URI本身就隐含了标识符,因为毕竟URI代表的是 独特的资源标识符
请注意,URI作为一个整体标识一个资源,并不一定意味着某种形式的父子结构。尤其是客户端根本不应该试图从URI中提取知识。
关于 PATCH
这取决于。通常情况下,我们应该使用一种用于打补丁的媒体类型,如 JSON补丁 或 JSON合并补丁.
前者的表示方式定义了某些字段,说明某个字段应该用给定的值添加、删除或替换,比如下面列出的一个符号。
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 Merge Patch的工作方式有所不同。它定义了一些默认规则,指示服务器如何将更改应用到目标文档中。像下面这样的文档,即会添加或更新字段。a 有价值 z 其后 f 的 c的对象必须被删除。该资源的所有其他剩余属性保持不变。
PATCH /target HTTP/1.1
Host: example.org
Content-Type: application/merge-patch+json
{
"a":"z",
"c": {
"f": null
}
}
这两种媒体类型都可以用来直接向 "集合"-资源发送请求,因为两者都可以针对定义中的子元素。然而,在缓存方面,我会尽量避免。
HTTP中的缓存事实上是在资源的URI上工作的。任何在URI上进行的不安全操作都会导致缓存对该目标的存储表示无效。例如,如果你之前调用了 GET /person/1
现在进行 PUT
或 PATCH
,这两个都是不安全的操作,对 /person
数据可能会被更新,尽管客户端请求的 GET /person/1
之后仍然可以通过缓存检索缓存响应,因为它不知道对该资源所做的任何更改。