27

我想为我的资源实现部分更新,因为我有大量资源并想从中更新部分信息。我已经浏览了以下链接,但无法
确定是使用 HTTP POST 还是 PATCH 方法。

REST 的 HTTP MODIFY 动词?

如何提交 RESTful 部分更新?

http://jacobian.org/writing/rest-worst-practices/

https://github.com/archiloque/rest-client/issues/79

https://datatracker.ietf.org/doc/html/draft-dusseault-http-patch-16

http://greenbytes.de/tech/webdav/draft-dusseault-http-patch-06.html

http://jasonsirota.com/rest-partial-updates-use-post-put-or-patch

http://bitworking.org/news/296/How-To-Do-RESTful-Partial-Updates

https://github.com/dharmafly/jsonpatch.js

请为此提出任何有效的解决方案。

4

3 回答 3

95

根据 RFC5789 ( https://www.rfc-editor.org/rfc/rfc5789 ),这正是 PATCH 的用途:

一些扩展超文本传输​​协议 (HTTP) 的应用程序需要一项功能来进行部分资源修改。现有的 HTTP PUT 方法只允许完全替换文档。该提案添加了一个新的 HTTP 方法 PATCH,以修改现有的 HTTP 资源。

PATCH 和 PUT 的区别描述为:

PUT 和 PATCH 请求之间的区别体现在服务器处理封闭实体以修改由 Request-URI 标识的资源的方式上。在 PUT 请求中,包含的实体被认为是存储在源服务器上的资源的修改版本,并且客户端请求替换存储的版本。然而,对于 PATCH,封闭的实体包含一组指令,描述如何修改当前驻留在源服务器上的资源以生成新版本。

还描述了 POST 的局限性:

PUT 方法已经定义为用一个完整的新主体覆盖资源,并且不能重用以进行部分更改。否则,代理和缓存,甚至客户端和服务器,可能会对操作的结果感到困惑。POST 已被使用,但没有广泛的互操作性(一方面,没有发现补丁格式支持的标准方法)[...]

我建议您阅读 RFC 并下定决心,但对我来说这似乎相当明确 - PATCH 请求应作为部分更新处理。(注意它们不是幂等的,不像 PUT。)

编辑:正如 Eugene 在评论中指出的那样,虽然 PATCH 请求是"neither safe nor idempotent as defined by [RFC2616]",但它们可以这样:

可以以幂等的方式发出 PATCH 请求,这也有助于防止在相似时间范围内同一资源上的两个 PATCH 请求之间的冲突导致不良结果。来自多个 PATCH 请求的冲突可能比 PUT 冲突更危险,因为某些补丁格式需要从已知的基点操作,否则它们会破坏资源。使用这种补丁应用程序的客户端应该使用条件请求,这样如果自客户端上次访问资源以来资源已更新,则请求将失败。例如,客户端可以在 PATCH 请求的 If-Match 标头中使用强 ETag [RFC2616]。

于 2012-02-29T09:23:42.510 回答
-1

您应该使用 RFC-7386“json merge PATCH”中描述的方法 PATCH。

例如,如果您想更改“a”的值并删除资源中的“f”,例如:

   {
     "a": "b",
     "c": {
       "d": "e",
       "f": "g"
     }
   }

您可以通过发送:

       PATCH /target HTTP/1.1
       Host: example.org
       Content-Type: application/merge-patch+json

       {
         "a":"z",
         "c": {
           "f": null
         }
       }
于 2017-11-09T09:03:54.907 回答
-16

PATCH 将与补丁格式一起使用,仅用于文档级别的补丁(也就是实际表示的差异)。将其用于其他目的是可疑且值得商榷的,而且尚不清楚该方法是为非媒体类型的用途而设计的。

一般来说,POST 是正确的方法,但您可能希望将资源拆分为多个资源并改为修改这些资源。

[为清楚起见进行了编辑,因为有些人不阅读评论]

于 2012-01-24T15:48:47.967 回答