资源的Http等幂部分修改最好实现为PUT而不是PATCH?

时间:2019-02-02 13:11:13

标签: rest http api-design

Http PATCH方法被认为是非幂等的,并对资源进行了部分修改

与幂等并应用资源替换的PUT相反。

(如MDN所述):

  

HTTP PATCH请求方法将部分修改应用于   资源。

     

HTTP PUT方法仅允许完全替换文档。   与PUT不同,PATCH不是幂等的,意味着连续相同   补丁程序请求可能会有不同的效果。

但是可以以幂等的方式实现PATCH (MDN):

  

然而,也可以   发出幂等的方式发出PATCH请求。

的幂等实现补丁的一个例子是:

path: /contact/:id
method: patch
body {
name: 'John'
}

不管这个请求将被做出的次数 - 资源将保持在相同的状态的第一个请求之后

由于幂等请求被优化(reference):

  

客户端可自动地,如果把它太取消GET请求   需要长时间重复处理,因为他们认为它具有相同的含义   效果(因为GET是幂等的)。但是,他们不会做同样的事情   POST请求的事情,因为第一个可能已经更改   服务器端的某些状态。

据我所知这种优化可以仅适用于由HTTP标准考虑幂等的HTTP方法。

因此,幂等PATCH请求我上面写不会被优化。 (据我了解,HTTP标准指出补丁不是幂等的,但并不禁止将补丁实现为幂等的。)

由于PUT被认为是幂等通过HTTP标准。 将/ contact /:id PATCH请求用作PUT是不是更可取(为了获得上述优化)?

更新1


我可以将请求修改为PUT,并以仅更新请求有效负载中发送的属性,而忽略未发送的属性的方式在服务器中实现。 以这种方式,我正在执行PUT请求,该请求以将被优化的幂等方式修改了部分资源,并且我没有替换整个资源。 如果资源很大并且我要进行的更改很小,是否发生事件,如果以幂等的方式实现,不是每次都使用PUT更好吗?

使我获得了标题: 资源的幂等局部修改最好用PUT代替PATCH来实现?


更新2:


如在此question答案表示:  12

其理由HTTP幂等局部的修改都没有更好,因为PUT实现为:的它违抗REST建筑设计

随之而来的一些缺点是:

  1. 其他程序员将不理解“部分更新PUT”,因此应编写有关该端点的更多文档。

  2. 将无法获取在先前的“部分更新PUT”中发送的确切资源。

  3. 由于剩下的就是专注于我们的API的长期演进,秉承 这样可以节省我们将来的时间。

可能还有更多不遵循REST架构风格的缺点...

但是,从性能的角度来看,如果请求是幂等的,则部分PUT更新会更好(因为它获得了上述优化)。

我会很乐意听到的一些想到:)更多的理由。

谢谢

1 个答案:

答案 0 :(得分:2)

  

据我了解,HTTP标准指出补丁不是幂等的,但并不禁止将补丁实现为幂等的。

是正确的。确切地说,该标准不能保证幂等语义。

  

资源的幂等部分修改最好用PUT代替PATCH来实现?

“取决于”。

是的,如果使用PUT,那么正确的是,通用组件将能够识别服务器承诺对请求进行幂等处理,因此自动重发消息是安全的(例如,等待响应到达。

使用PATCH时,您不会得到相同的行为,因为中介程序需要了解补丁文档的媒体类型,并深入研究请求有效负载,以找出发生的情况。

但是...没有“部分PUT”之类的东西。如果所需的资源表示形式很大,并且您要进行的更改很小,那么发送补丁文档而不是完整的表示形式很有意义。

选择权归结于顾虑-您遇到的哪些问题最重要,哪些可以解决。

  

为什么不存在这样的部分PUT?

因为HTTP语义不是那样定义的。 RFC 7231

  

PUT方法请求创建目标资源的状态或将其替换为由请求消息有效负载中包含的表示形式定义的状态。给定表示形式的成功PUT将表明,在同一目标资源上进行后续GET将导致在200(OK)响应中发送等效表示形式。

PUT并不意味着“对此请求应用幂等处理”。它表示替换;类似于覆盖文件系统或变量集上的文件。

请记住,统一接口是REST约束之一-这就是使我们能够使用通用组件以标准方式进行通信的原因。

如果要遵循REST约束,进行幂等局部替换,那么您要做的就是为新方法创建规范。有一个定义明确的process和一个registry,您可以在其中查找已通过流程的方法的标准。

定义了方法之后,组件提供者可以决定是否选择加入并支持您的新标准。

以另一种方式表达想法:在控制客户端和服务器的情况下,将自定义语义嵌入消息中没有任何问题。但是,如果要使用一种标准方法类型执行此操作,则应使用POST,因为这是通用组件将对发生的情况做出最少假设的方法。