PUT、POST和PATCH有什么区别?

559

HTTP协议中PUT、POST和PATCH方法有什么区别?


2
https://dev59.com/HHRB5IYBdhLWcg3wa2q2#2590281 - Nowhere man
4
可能是PUT和POST在REST中的区别的重复问题。 - Nowhere man
58
在现代Web API中,除了GET/POST之外使用其他方法是不明智的。许多人这样做。在大多数现代应用程序中,标识URI并不是要替换、更新等资源。它们不是文档,而是正在调用的过程。除了调用的方法之外,URI本身很少标识实际资源。因此,对于查询字符串请求请使用GET,对于需要在请求正文中发布JSON数据或文件的情况,请使用POST。在我看来,任何其他方法都是试图将涉及URI和静态HTML文档上的操作的过时概念塞入看起来完全不同的新架构中。 - Triynko
1
所有的答案都很好。我只是想分享一下它们之间的区别以及何时应该使用每个选项 - Train
15
@Triynko,你似乎陷入了Richardson成熟度模型的0级,是时候继续前进了:https://martinfowler.com/articles/richardsonMaturityModel.html - Marcel Toth
显示剩余3条评论
13个回答

399

HTTP动词PUT、POST、GET、DELETE和PATCH之间的区别:

最常用的HTTP动词POST、GET、PUT、DELETE类似于数据库的CRUD(创建、读取、更新和删除)操作。我们使用大写字母来指定这些HTTP动词。下面是它们之间的比较:

  1. 创建 - POST
  2. 读取 - GET
  3. 更新 - PUT
  4. 删除 - DELETE

PATCH:提交对资源的部分修改。如果只需要更新资源的一个字段,则可以使用PATCH方法。

注意:
由于POST、PUT、DELETE会修改内容,因此在下面的URL上使用Fiddler测试只是模拟更新,实际上并不会进行删除或修改。我们只能通过查看状态码来检查是否发生插入、更新或删除。

URL: http://jsonplaceholder.typicode.com/posts/

  1. GET:

GET是最简单的HTTP请求方法;每次单击链接或在地址栏中输入URL时,浏览器都会使用它。它指示服务器将由URL标识的数据传输到客户端。数据不应该被修改,因为GET请求是只读的。

使用Fiddler或PostMan进行检查:我们可以使用Fiddler来检查响应。打开Fiddler并选择Compose选项卡。指定动词和URL,如下所示,然后单击Execute以检查响应。

Verb: GET

url: http://jsonplaceholder.typicode.com/posts/

Response: 您将获得以下响应:

"userId": 1,  "id": 1,  "title": "sunt aut...",  "body": "quia et suscipit..."

在“成功”(或无错误)路径中,GET会返回XML或JSON表示形式以及HTTP响应代码200(OK)。在错误情况下,它通常返回404(未找到)或400(错误请求)。

2) POST:

POST动词主要用于创建新资源。特别是用于创建从属资源。也就是说,从某些其他(例如父级)资源创建的资源。

成功创建后,返回HTTP状态201,并返回一个Location标头,其中包含具有201 HTTP状态的新创建资源的链接。

使用Fiddler或PostMan进行检查:我们可以使用Fiddler来检查响应。打开Fiddler并选择Compose选项卡。如下所示指定动词和URL,并单击执行以检查响应。

动词:POST

URL:http://jsonplaceholder.typicode.com/posts/

请求正文:

data: {
   title: 'foo',
   body: 'bar',
   userId: 1000,
   Id : 1000
}

响应: 您将收到201的响应代码。

如果要检查ID为1000的插入记录,请更改动词为“Get”并使用相同的URL,然后单击执行。

如前所述,上述URL仅允许读取(GET),我们无法实时读取更新后的数据。

3) PUT:

PUT通常用于更新功能,将请求正文放置在已知资源URI中的PUT,其中包含原始资源的新更新表示。

使用Fiddler或PostMan进行检查: 我们可以使用Fiddler检查响应。 打开Fiddler并选择Compose选项卡。 指定动词和URL如下所示,然后单击执行以检查响应。

动词:PUT

URL:http://jsonplaceholder.typicode.com/posts/1

请求正文:

data: {
   title: 'foo',
   body: 'bar',
   userId: 1,
   Id : 1
}

响应:如果成功更新,PUT请求将返回状态码200(如果在正文中没有返回任何内容,则返回204)。

4) DELETE:

DELETE非常容易理解。它用于删除由URI标识的资源。

如果删除成功,则返回HTTP状态码200(OK)以及响应主体,可能是已删除项的表示(通常需要太多带宽),或包装响应(请参见下面的返回值)。 或者,返回没有响应主体的HTTP状态码204(NO CONTENT)。换句话说,建议使用没有主体的204状态,或JSEND风格的响应和HTTP状态码200。

使用Fiddler或PostMan检查: 我们可以使用Fiddler来检查响应。打开Fiddler并选择Compose选项卡。 按照下面所示指定动词和URL,然后单击Execute以检查响应。

动词:DELETE

URL: http://jsonplaceholder.typicode.com/posts/1

响应:如果成功删除,则返回HTTP状态码200(OK)以及响应主体。

PUT和PATCH之间的示例

PUT

如果我必须更改我的名字,则发送PUT请求进行更新:

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

因此,为了更新名字,我们需要再次发送所有数据的参数。

PATCH:

PATCH请求表示我们只发送需要修改的数据,而不修改或影响其他数据的部分。 例如:如果我们只需要更新名字,我们只传递名字。

更多信息,请参考以下链接:


160
PUT不是更新操作。PUT的作用是在给定的URI上创建或替换实体。根据HTTP规范,PUT是幂等的。虽然它可以用于更新,但仅将其视为更新操作是不正确的。 - Maladon
7
我同意PUT不是更新操作,它可以与replace映射,因为当你发送PUT请求时,它会覆盖掉现有的资源。但是如果我们发送PATCH请求,它只会替换指定的条目。 - Atul Chavan
1
因为PUT也可以用于创建,所以我不确定你的回答表明我应该使用哪个? - Rob P.
3
这个回答比较好,但与PATCH相比还有欠缺:https://dev59.com/HHRB5IYBdhLWcg3wa2q2#630475 - Vadorequest
你应该在头部指定Content-Type,而RequestBody的格式如下:title=foo&body=bar&userid=1000&id=1000 - Shayan
显示剩余6条评论

150
以下定义来自实际世界的例子。
示例概览: 对于每个客户端数据,我们都存储一个标识符以查找该客户端数据,并将该标识符发送回客户端以供参考。
1. POST 如果客户端发送没有标识符的数据,则我们将存储数据并分配/生成新的标识符。 如果客户端再次发送相同的没有标识符的数据,则我们将存储数据并分配/生成新的标识符。 注意:这里允许重复。
2. PUT 如果客户端发送带有标识符的数据,则我们将检查该标识符是否存在。如果标识符存在,我们将使用数据更新资源;否则,我们将使用数据创建一个资源并分配/生成新的标识符。
3. PATCH 如果客户端发送带有标识符的数据,则我们将检查该标识符是否存在。如果标识符存在,我们将使用数据更新资源;否则,我们将抛出异常。
注意:在PUT方法中,如果找不到标识符,我们不会抛出异常。但在PATCH方法中,如果找不到标识符,我们会抛出异常。

如果你对上述内容有任何疑问,请告诉我。


5
简明清晰的解释! - Jay Dadhania
1
@Yokesh Waran 你好,我对你的回答进行了一些编辑。看看它们是否可以接受。 - akinuri
1
真棒的简单!!! - Saurabh Chaturvedi
最好的。特别是PUT和PATCH之间的区别。 - ShaileshKumarMPatel
很好的解释,但如果这就是PUT和POST的意思,那么RFC的作者们应该被打一顿。感觉他们想让事情押韵,以'P'开头的东西。 - nawfal

135

以下是所有内容的简单描述:

  • POST 用于创建资源(不管是否重复)
  • PUT 用于检查资源是否存在,然后更新,否则创建新的资源
  • PATCH 用于更新资源

5
这并非完全准确。RFC规定,“POST方法请求目标资源根据资源自身的语义处理请求中所包含的表示形式”,而“将数据添加到资源的现有表示形式”只是其中一个提供的例子。详见https://tools.ietf.org/html/rfc7231#section-4.3.3。 - Chomeh
1
@Chomeh,这些语义/ RFC 是在哪个层面上定义的?它是框架或语言级别的配置,还是特定于框架的某个特定部分?比如,Node 的 POST/PUT/PATCH 是否与 Ruby on Rails 的不同? - stevec
2
@stevec 应用程序/API。例如,您可以设计一个接受 POST 到 /delete 的 API,但不一定要创建新资源的结果(例如 /deletions/{id})。 - Chomeh
换句话说:POST:创建一个新的资源并将客户端指向其表示,无论是在请求结束时返回表示还是通过重定向。 - truefusion

87

3
似乎 PUT 的意思是“更新并覆盖”,而 PATCH 的意思是“更新并合并”。我只是在试图想出一致而简洁的术语来描述你的答案很好地解释了什么。 - MikeyE

50

简单解释:

POST - 创建新的记录

PUT - 如果记录存在则更新,否则创建新的记录

PATCH - 更新

GET - 读取

DELETE - 删除


4
你想知道这个问题与大约两周前Kwame的回答有何实质性不同。 - ruffin

28

这样来想...

POST - 创建

PUT - 替换

PATCH - 更新

GET - 读取

DELETE - 删除


4
“我可能会添加这个区别:’如果客户端决定了结果资源的地址,则使用PUT,如果服务器决定则使用POST。‘” - ruffin

25

请求类型

  • 创建 - POST
  • 读取 - GET
  • 创建或更新 - PUT
  • 删除 - DELETE
  • 更新 - PATCH

GET/PUT是幂等的(idempotent)
PATCH有时也可以是幂等的

什么是幂等性 - 它意味着如果我们多次发出同一个查询,它不应该影响其结果。(相同输出。假设一头母牛怀孕了,如果我们再次配种它,则不能使其多次怀孕)

get :-

简单获取。从服务器获取数据并向用户显示。

{
id:1
name:parth
email:x@x.com
}

post :-

在数据库中创建新资源。它意味着添加新数据。它不是幂等的。

put :-

创建新资源或添加到现有资源。 是幂等的,因为每次都会更新相同的资源并输出相同的结果。 例如: - 初始数据

{
id:1
name:parth
email:x@x.com
}
  • 执行put-localhost/1 输入电子邮件:ppp@ppp.com
  • perform put-localhost/1 put email:ppp@ppp.com
{
id:1
email:ppp@ppp.com
}

补丁

现在是补丁请求 PATCH 有时可能是幂等的。

id:1
name:parth
email:x@x.com
}

补丁名称:w

{
id:1
name:w
email:x@x.com
}
HTTP方法
GET:是的
POST:不是
PUT:是的
PATCH:不是*
OPTIONS:是的
HEAD:是的
DELETE:是的

资源:
幂等性--什么是幂等性?

"有时候" 幂等 究竟意味着什么?是什么决定了幂等性? - Polv
“有时幂等” === 不是幂等 - 它要么是幂等的,要么不是,没有中间状态。 - Jay Dadhania
我可以从注释中读到PUT更改资源,但必须发送整个属性集。那么你怎么能做“put email:ppp@ppp.com”呢?难道不应该是put {id:1 name:parth email:ppp@ppp.com}吗? - arsene stein

21
PUTPATCH请求的主要差异:
假设我们有一个保存人名姓氏的资源。
如果我们想要修改名字,那么我们发送一个PUT请求进行更新。 { "first": "Michael", "last": "Angelo" }
在这里,虽然我们只更改了名字,但是使用PUT请求时我们必须同时发送所有参数,包括名字和姓氏。换句话说,我们必须再次发送全部有效负载。
然而,当我们发送PATCH请求时,我们只发送想要更新的数据。换句话说,我们只发送名字以进行更新,不需要发送姓氏。

5

参考 RFChttps://www.rfc-editor.org/rfc/rfc9110.html#name-method-definitions

POST - 创建新对象
PUT - 更新旧对象或如果不存在则创建新对象
PATCH - 更新/修改旧对象。主要用于修改。

正如之前提到的,RFC有几种解释,但是如果仔细阅读,您会注意到PUT和PATCH方法在POST之后出现,这是创建本地HTML表单的常见老式方式。

因此,如果您尝试支持所有方法(例如PATCH或DELETE),则可以建议使用CRUD模型的最合适方法:

Create - PUT
Read - GET
Update - PATCH
Delete - DELETE

旧的HTML本地方式:
读取 - GET
创建/更新/删除 - POST

祝编程者好运!;-)


1

PUT和PATCH在替换/更新时发送完整数据和部分数据之间的区别是非常逻辑的。然而,以下只有几点需要注意:

  1. 有时候POST被视为相对于PUT用于更新
  2. HTTP是否强制/检查在PATCH中发送完整数据还是部分数据?否则,PATCH可能与PUT / POST中的更新相同。

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