PATCH与PUT and POST

另外:区分PATCH与PUT、POST方法

  在HTTP原本的定义中[RFC2616],用于上传数据的方法只有POST和PUT。后来鉴于POST和PUT语义和功能上的不足,又加入了PATCH方法[RFC5789]。POST与PUT方法的差异是显而易见的,而PUT与PATCH方法就比较相似,但它们的用法却完全不同。

  PUT方法和PATCH方法所请求的目标地址都是直接指向资源的,而POST方法请求的目标是一个行为处理器,这点很容易区分。但PUT和PATCH呢?根据规范中所介绍的PUT用于替换资源,而PATCH用于更新部分资源。仅凭这个描述,我无法理解他们的区别,直到看到后面介绍PATCH是非幂等的时候才恍然大悟。

  从这里开始要考虑一个问题,PATCH为什么是非幂等的呢?POST方法非幂等可以理解,因为它请求服务器执行一个动作,多次发起请求可能导致动作多次执行。而像PATCH这样请求的目标是一个资源的,如果它只是更新一个资源,不执行其它动作,又何来不幂等呢?其实是我忽略了一个问题,PATCH方法和POST方法有个很相似的地方,它们的实体部分都是结构化的数据。POST方法的实体结构一般是 multipart/form-data 或 application/x-www-form-urlencoded 而PATCH方法的实体结构则随其它规范定义。这和PUT方法的无结构实体相比就是最大的区别。

  PUT方法的实体无结构的,它直接把实体部分的数据替换到服务器的资源上。而PATCH提供的实体则需要根据程序或其它协议的定义,解析后在服务器上执行,以此来修改服务器上的数据。也就是说,PATCH请求是会执行某个程序的,如果重复提交,程序可能执行多次,对服务器上的资源就可能造成额外的影响,这就可以解释它为什么是不幂等的了。

  举个例子,如果服务器上有个资源/abc.int,里面存放一个整数,值为 1。也就是说,GET这个资源的话,服务器响应的实体只包含了 1 这个数字。现在在自己的框架中定义当提交PATCH请求,实体匹配^+\d+$的格式时就对服务器资源中的数字执行一个加法操作。于是当客户端向/abc.int地址发起PATCH请求,实体部分为+3之后,服务器的/abc.int资源中的数据就变成 4,也就是说,GET它会得到 4。如果客户端不小心重复提交了PATCH请求,那么+3就会被再执行一次,这个资源的数据就变成 7。

  这么一看,PATCH和PUT的区别就非常明显了吧。

序号 方法 描述

1 GET 请求指定的页面信息,并返回实体主体。

2 HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头

3 POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。

4 PUT 从客户端向服务器传送的数据取代指定的文档的内容。

5 DELETE 请求服务器删除指定的页面。

6 CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

7 OPTIONS 允许客户端查看服务器的性能。

8 TRACE 回显服务器收到的请求,主要用于测试或诊断。

9 PATCH 实体中包含一个表,表中说明与该URI所表示的原内容的区别。

10 MOVE 请求服务器将指定的页面移至另一个网络地址。

11 COPY 请求服务器将指定的页面拷贝至另一个网络地址。

12 LINK 请求服务器建立链接关系。

13 UNLINK 断开链接关系。

14 WRAPPED 允许客户端发送经过封装的请求。

15 Extension-mothed 在不改动协议的前提下,可增加另外的方法。

草案规范:https://tools.ietf.org/html/rfc5789

2. The PATCH Method

The PATCH method requests that a set of changes described in the
​ request entity be applied to the resource identified by the Request-
​ URI. The set of changes is represented in a format called a “patch
​ document” identified by a media type. If the Request-URI does not
​ point to an existing resource, the server MAY create a new resource,
​ depending on the patch document type (whether it can logically modify
​ a null resource) and permissions, etc.

Dusseault & Snell Standards Track [Page 2]

RFC 5789 HTTP PATCH March 2010

The difference between the PUT and PATCH requests is reflected in the
​ way the server processes the enclosed entity to modify the resource
​ identified by the Request-URI. In a PUT request, the enclosed entity
​ is considered to be a modified version of the resource stored on the
​ origin server, and the client is requesting that the stored version
​ be replaced. With PATCH, however, the enclosed entity contains a set
​ of instructions describing how a resource currently residing on the
​ origin server should be modified to produce a new version. The PATCH
​ method affects the resource identified by the Request-URI, and it
​ also MAY have side effects on other resources; i.e., new resources
​ may be created, or existing ones modified, by the application of a
​ PATCH.

PATCH is neither safe nor idempotent as defined by [RFC2616], Section