PATCH请求和PUT请求有什么主要区别?

256

我在我的Rails 应用中使用了 PUT 请求。现在,浏览器已经实现了一个新的HTTP动词 PATCH。所以,我想知道 PATCHPUT 请求之间的主要区别是什么,并且我们应该在何时使用其中之一。

10个回答

169
HTTP动词可能是HTTP协议中最晦涩的东西之一。它们存在,而且有很多种,但是为什么它们存在呢?
Rails似乎想要支持许多动词,并添加一些不被Web浏览器本地支持的动词。
这里是HTTP动词的详尽列表:http://annevankesteren.nl/2007/10/http-methods 这是来自官方RFC的HTTP patch:https://datatracker.ietf.org/doc/rfc5789/?include_text=1 “PATCH”方法请求将请求实体中描述的一组更改应用于由“Request-URI”标识的资源。这组更改以称为“补丁文档”的格式表示,该格式由媒体类型标识。如果“Request-URI”不指向现有资源,则服务器可以根据补丁文档类型(无论它是否可以逻辑修改空资源)和权限等创建新资源。 “PUT”和“PATCH”请求之间的区别反映在服务器处理封装实体以修改由“Request-URI”标识的资源的方式上。在“PUT”请求中,封装实体被认为是存储在原始服务器上的资源的修改版本,并且客户端请求替换存储的版本。然而,“PATCH”中,封装实体包含一组说明如何修改当前驻留在原始服务器上的资源以生成新版本的指令。 “PATCH”方法影响由“Request-URI”标识的资源,它还可能对其他资源产生副作用;即,应用程序可以通过“PATCH”创建新资源或修改现有资源。
据我所知,在Rails应用程序中通常不使用动词...就我所理解的,RFC patch动词应该被用于发送补丁指令,就像你在两个文件之间做差异时一样。你不需要再次发送整个实体,而是只需发送一个大小比重新发送整个实体要小得多的补丁。

想象一下,你想编辑一个大文件。你只编辑了3行。你只需要发送差异就可以了,而不是把整个文件都发回去。另外,发送补丁请求还可以用于异步合并文件。版本控制系统可以潜在地使用动词来远程更新代码。

另一个可能的用例与NoSQL数据库有些相关,它可以存储文档。假设我们使用JSON结构从服务器向客户端发送和接收数据。如果我们想要删除一个字段,我们可以使用类似于mongodb的$unset的语法。实际上,mongodb中用于更新文档的方法可能可以用来处理json补丁。

以这个例子为例:

db.products.update(
   { sku: "unknown" },
   { $unset: { quantity: "", instock: "" } }
)

我们可以有这样的东西:
PATCH /products?sku=unknown
{ "$unset": { "quantity": "", "instock": "" } }

最后,人们可以说他们想说的关于HTTP谓词的任何话。只有一个真相,而这个真相在RFC中。


1
需要注意的是,RFC 5789仍处于提案阶段,尚未正式接受,并且目前被标记为“勘误存在”。这种“最佳实践”备受争议,从技术上讲,PATCH尚未成为HTTP标准的一部分。唯一的真相是,由于RFC未被接受,您不应该这样做。 - fishpen0
3
尽管它仍处于提议阶段,但这并不意味着它不应该被使用。如果是这样的话,我们就无法使用WebSockets和许多其他仍处于提案状态的RFC。实施该提案比实施完全自定义的东西要好100倍,因为没有其他人会实施它。 - Loïc Faure-Lacroix
@LoïcFaure-Lacroix,我建议你参与IETF标准制定过程;在IETF的上下文中,“拟议标准”意味着什么,你严重误解了。核心HTTP/1.1规范本身被标记为“拟议”,这应该是一个提示…… - Julian Reschke
1
@JulianReschke https://en.wikipedia.org/wiki/Internet_Standard#Proposed_Standard ... 这不是我的话。建议标准并不意味着你不能像我上面解释的那样很好地实现它。这并不意味着它不稳定,不能实现...但除非标记为互联网标准,否则仍处于提案阶段...我不确定你是如何争论的。它被称为“建议标准”,它不能意味着任何其他建议。如果你想争论一个建议标准可以被使用。这正是我写的。 - Loïc Faure-Lacroix
@LoïcFaure-Lacroix 我的观点是,认为某个东西不是HTTP的一部分是没有意义的,因为它只是一个“拟议的标准”,而HTTP本身也只是一个拟议的标准。所以,“PATCH”和“GET”一样标准。结束通话。 - Julian Reschke
显示剩余4条评论

142

我花了几个小时在谷歌上搜索,找到了答案这里

PUT => 如果用户可以更新整个记录或仅部分记录,请使用PUT(用户控制更新内容)

PUT /users/123/email
new.email@example.org

PATCH => 如果用户只能更新部分记录,例如仅限电子邮件地址(应用程序控制可以更新的内容),请使用PATCH。

PATCH /users/123
[description of changes]

为什么要用Patch?

PUT方法需要更多的带宽或处理完整资源而不是部分资源。因此,引入了PATCH来减少带宽。

PATCH的解释

PATCH是一种既不安全,也不幂等的方法,允许对其他资源产生全面或部分更新和副作用。

PATCH是一种方法,其中封闭的实体包含一组说明,描述当前驻留在源服务器上的资源应如何修改以生成新版本。

PATCH /users/123
[
  { "op": "replace", "path": "/email", "value": "new.email@example.org" }
]

这里有关于put和patch的更多信息


8
为什么这个补丁不安全? - Bishisht Bhatta
3
在HTTP协议中,PATCHPOSTPUT等不同,因为它修改了您的数据(具有副作用)。与GETOPTIONS等安全方法不同,您可以多次调用这些端点而不会产生任何副作用。 - Mike Doe
8
PATCH并不是仅为了节省带宽而引入的。正如RFC 5789所述:
“需要一种新的方法来提高互操作性并防止错误。”
在多并行环境中,如果只有包含其余有效负载的PUT请求,则会增加修改资源的其他属性的风险。PATCH解决了这个问题。
- Tomasz Nazar

129

put:
如果我想要更新我的first名字,那么我发送一个put请求:

{ "first": "Nazmul", "last": "hasan" } 

但是使用put请求存在一个问题:当我想发送put请求时,我必须发送所有两个参数,即firstlast(而我只需要更新first),因此必须再次发送它们以进行put请求。

patch:
另一方面,patch请求表示:仅指定需要updatedata,不会影响或更改其他数据。因此,无需再次发送所有值。我只需要更改first名字吗?在patch请求中,仅需指定first即可。


8
我认为这是最直接的答案。 - Fortune
2
快速易懂! - Ziyad Mansy
2
我的最爱,直戳要害!完美。 - Thiago Prochnow
1
是的,简洁准确。 - Sumitiscreative
2
长话短说 - R Sun

31

以下是HTTP协议中POST、PUT和PATCH方法的不同之处。

POST

HTTP.POST方法总是在服务器上创建一个新资源。这是一个非幂等请求,即如果用户两次发送相同的请求,则会在没有约束条件的情况下创建另一个新资源。

HTTP POST方法类似于SQL中的INSERT查询,它总是在数据库中创建一个新记录。

示例:使用POST方法保存新用户、订单等,其中后端服务器为新资源决定资源ID。

PUT

在HTTP.PUT方法中,首先从URL中标识资源,如果存在,则更新该资源;否则,创建一个新资源。当目标资源存在时,用全新的内容覆盖该资源。也就是说,HTTP.PUT方法用于创建或更新资源。

HTTP PUT方法类似于SQL中的MERGE查询,根据给定的记录是否存在,插入或更新记录。

PUT请求是幂等的,即连续发送相同的请求会更新现有记录(不会创建新记录)。在PUT方法中,客户端决定资源ID,并在请求URL中提供该ID。

示例:使用PUT方法更新现有用户或订单。

PATCH

HTTP.PATCH方法用于对资源进行部分修改,即增量更新。

http patch方法类似于SQL中的UPDATE查询,仅设置或更新所选列,而不是整行。

例如:您可以使用PATCH方法来更新订单状态。

PATCH /api/users/40450236/order/10234557

请求正文: {status: '已交付'}


干得好!不言自明。 - Ziyad Mansy

19

类比解释

我的一位讲师购买了一辆阿尔法·罗密欧。它的发动机有缺陷(真是个意外)。

解决这个问题有两种方式:

  • 替换整辆车(提交请求),或者
  • 只是替换有缺陷的发动机(修补请求)- 即“修补”车子,而不是完全替换。

不为提及品牌而道歉。

他会唠叨着说,当他抱怨时,经销商竟然当面嘲笑他。

如果你制造有缺陷的汽车,并且拒绝替换它们(通过你的经销商),那你就应该得到即将到来的声誉。“意大利垃圾”。这是一个实至名归的声誉。想要可靠性?买日本车。

例子:

GET toyota_inspection # inspect the car at the dealership, see the new Toyota
POST toyota_path # manufacture the car

PUT toyota_path ## (you should know the answer to this one!?)
PATCH toyota_path, params: {engine: 4_cyclinder, seats: nappa_leather} ## What is this doing? 

例子/故事用来帮助加强概念,否则你可能在10秒后就会忘记。

9

在进行更新时,PUT和PATCH都有其局限性。使用PUT需要我们指定所有属性,即使我们只想更改一个属性也是如此。 但是,如果我们使用PATCH方法,我们可以仅更新所需的字段,而无需提及所有字段。 PATCH不允许我们修改数组中的值或删除属性或数组条目。


5
根据HTTP术语,“PUT”请求就像数据库更新语句一样。 “PUT”用于修改现有资源(之前发布的),而“PATCH”请求则用于更新现有资源的某些部分。
例如:
客户详细信息:
// This is just a example.

firstName = "James";
lastName = "Anderson";
email = "email@domain.com";
phoneNumber = "+92 1234567890";
//..

当我们想要更新整个记录时,我们必须使用 HttpPUT 动词。

例如:

// Customer Details Updated.

firstName = "James++++";
lastName = "Anderson++++";
email = "email@Updated.com";
phoneNumber = "+92 0987654321";
//..

另一方面,如果我们只想更新记录的某个部分而不是整个记录,则使用 Http PATCH verb例如:

   // Only Customer firstName and lastName is Updated.

    firstName = "Updated FirstName";
    lastName = "Updated LastName";
   //..

PUT VS POST:

使用PUT请求时,我们必须发送所有参数,如firstName,lastName,email,phoneNumber。而在patch请求中,只发送要更新的参数,不会影响或更改其他数据。

更多详情请访问:https://fullstack-developer.academy/restful-api-design-post-vs-put-vs-patch/


2

PUTPATCH方法在本质上相似,但有一个关键的区别。

PUT - 在PUT请求中,被包含的实体将被视为服务器上资源的修改版本,并将被此修改实体替换。

PATCH - 在PATCH请求中,被包含的实体包含一组指令,指导如何修改服务器上的实体以生成新版本。


0

Put方法和Patch方法相似。但在Rails中,它们有不同的用法。 如果我们想要更新/替换整个记录,则必须使用Put方法。 如果我们想要更新特定记录,则使用Patch方法。


0
PUT和PATCH之间的区别 PUT请求和PATCH请求的主要区别在于服务器处理包含实体以更新由请求URI标识的资源的方式。当进行PUT请求时,所包含的实体被视为原始服务器上保存的资源的修改版本,并且客户端请求替换它。然而,使用PATCH时,所包含的实体具有一组说明,描述了应如何部分修改存储在原始服务器上的资源以创建新版本。
第二个区别是幂等性。HTTP PUT被认为是幂等的,因为每次进行多个请求后,它总是产生相同的结果。另一方面,HTTP PATCH基本上被认为是非幂等的。但是,根据其实现位置,它可以被设置为幂等。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接