【发布时间】:2022-12-24 01:03:55
【问题描述】:
首先,一些定义:
PUT 在Section 9.6 RFC 2616 中定义:
PUT 方法请求将封闭的实体存储在提供的 Request-URI 下。如果 Request-URI 引用一个已经存在的资源,则包含的实体应该被视为驻留在原始服务器上的版本的修改版本.如果 Request-URI 不指向现有资源,并且该 URI 能够被请求用户代理定义为新资源,则源服务器可以使用该 URI 创建资源。
PATCH定义在RFC 5789:
PATCH 方法要求一组变化中描述的 请求实体应用于由 Request- 标识的资源 网址。
同样根据RFC 2616 Section 9.1.2 PUT 是幂等的,而 PATCH 不是。
现在让我们来看一个真实的例子。当我使用数据
{username: 'skwee357', email: 'skwee357@domain.example'}POST 到/users并且服务器能够创建资源时,它将以 201 和资源位置(假设为/users/1)进行响应,并且下一次调用 GET/users/1将返回{id: 1, username: 'skwee357', email: 'skwee357@domain.example'}。现在假设我想修改我的电子邮件。电子邮件修改被认为是“一组更改”,因此我应该用“patch document”修补
/users/1。在我的例子中,它将是 JSON 文档:{email: 'skwee357@newdomain.example'}。然后服务器返回 200(假设权限没问题)。这让我想到第一个问题:
- PATCH 不是幂等的。它在 RFC 2616 和 RFC 5789 中是这样说的。但是,如果我发出相同的 PATCH 请求(使用我的新电子邮件),我将获得相同的资源状态(我的电子邮件被修改为请求的值)。为什么 PATCH 不是幂等的?
PATCH 是一个比较新的动词(RFC 于 2010 年 3 月引入),它来解决“修补”或修改一组字段的问题。在引入 PATCH 之前,大家都使用 PUT 来更新资源。但是引入PATCH之后,让我很困惑PUT是干什么用的。这让我想到了第二个(也是主要的)问题:
- PUT 和 PATCH 之间的真正区别是什么?我在某处读到 PUT 可能用于代替特定资源下的整个实体,因此应该发送完整的实体(而不是像 PATCH 那样的属性集)。这种情况的实际用途是什么?您什么时候想替换/覆盖特定资源 URI 上的实体,为什么不考虑更新/修补实体这样的操作?我看到的 PUT 的唯一实际用例是在集合上发出 PUT,即
/users以替换整个集合。在引入 PATCH 之后,在特定实体上发布 PUT 就没有意义了。我错了吗?
【问题讨论】:
-
a) 它是 RFC 2616,而不是 2612。b) RFC 2616 已经过时,PUT 的当前规范在greenbytes.de/tech/webdav/rfc7231.html#PUT 中,c) 我不明白你的问题;不是很明显 PUT 可以用来替换任何资源,而不仅仅是一个集合,d) 在引入 PATCH 之前,人们通常使用 POST,e) 最后,是的,a具体的PATCH 请求(取决于补丁格式)能够是幂等的;只是不是一般。
-
如果有帮助,我已经写了一篇关于 PATCH 与 PUT eq8.eu/blogs/36-patch-vs-put-and-the-patch-json-syntax-war 的文章
-
简单:POST 在集合中创建一个项目。 PUT 替换一个项目。 PATCH 修改一个项目。 POST 时,计算新项目的 URL 并在响应中返回,而 PUT 和 PATCH 需要请求中的 URL。正确的?
-
datatracker.ietf.org/doc/html/rfc5789#section-2 PATCH 不是幂等的。
-
抱歉@theking2 网址已更改为blog.eq8.eu/article/put-vs-patch.html
标签: json rest http put http-method