REST中的PUT与POST

http rest post put


根据HTTP/1.1规范。

POST 方法用来请求原始服务器接受被附在请求由标识的资源的新下属实体 Request-URIRequest-Line

换句话说, POST 用于创建

PUT 将所附实体所提供的下储存方法请求 Request-URI 。如果 Request-URI 引用了已经存在的资源,则应将封闭的实体视为驻留在原始服务器上的实体的修改版本。如果 Request-URI 没有指向现有资源,并且请求用户代理能够将该URI定义为新资源,则原始服务器可以使用该URI创建资源。”

也就是说, PUT 用于创建或替换

那么,创建一个资源应该用哪个?还是需要同时支持两个?




Answer 1 Brian R. Bondy


Overall:

PUT和POST都可以用来创建。

你必须问 "你执行这个动作是为了什么?"来区分你应该使用什么。让我们假设你正在设计一个用于提问的API。如果你想使用POST,那么你会对一个问题列表进行操作。如果你想使用PUT,那么你会对一个特定的问题进行操作。

两者都可以使用,因此在RESTful设计中应该使用哪一个:

你不需要同时支持PUT和POST。

使用哪一个由你自己决定。但只要记住根据你在请求中引用的对象,使用正确的。

一些考虑因素:

  • 你是明确地命名你创建的URL对象,还是让服务器决定?如果你给它们命名,那么使用PUT。如果你让服务器决定,那么使用POST。
  • PUT是幂等的,所以如果你把一个对象PUT两次,它就没有任何效果。这是一个很好的属性,所以我会在可能的情况下使用PUT。
  • 您可以用PUT更新或创建一个具有相同对象URL的资源。
  • 通过POST,你可以有2个请求同时进入,对一个URL进行修改,它们可能会更新对象的不同部分。

一个例子:

我写了以下内容作为对此的另一个答案的一部分

POST:

用于修改和更新资源

POST /questions/<existing_question> HTTP/1.1
Host: www.example.com/

请注意,以下是一个错误。

POST /questions/<new_question> HTTP/1.1
Host: www.example.com/

如果尚未创建URL,则在指定名称时不应使用POST来创建URL。这将导致“找不到资源”错误,因为 <new_question> 还不存在。您应该 先在服务器上放置 <new_question> 资源。

不过你可以这样做,用POST创建一个资源。

POST /questions HTTP/1.1
Host: www.example.com/

请注意,在这种情况下,没有指定资源名称,新对象的URL路径将返回给你。

PUT:

用于创建一个资源,或覆盖它。当你指定资源的新URL时。

对于新资源。

PUT /questions/<new_question> HTTP/1.1
Host: www.example.com/

要覆盖现有资源。

PUT /questions/<existing_question> HTTP/1.1
Host: www.example.com/

此外,更简洁一点的是RFC 7231第4.3.4节PUT状态(添加了强调),

4.3.4。放

PUT方法请求 created 目标资源 的状态或 replaced 为请求消息有效负载中包含的表示形式所定义的状态。




Answer 2 Cheeso


你可以在网上找到一些论断,说

都不太对。


更好的是根据操作的幂等性在PUT和POST之间进行选择。

PUT意味着放置资源-用另一件事完全替换给定URL上可用的任何内容。根据定义,PUT是幂等的。随意执行多次,结果是相同的。 x=5 是幂等的。您可以放置​​一个资源,无论它先前是否存在(例如,创建或更新)!

POST更新资源,添加辅助资源或引起更改。POST不是幂等的,因为 x++ 不是幂等的。


按照这个说法,PUT是在知道要创建的东西的URL时,用于创建。POST是在知道要创建的事物类别的 "工厂 "或管理者的URL时,可以用来创建。

so:

POST /expense-report

or:

PUT  /expense-report/10929



Answer 3 Nigel Thorne


  • POST到URL 服务器定义的URL上创建子资源
  • 放置到URL 客户端定义的 URL上完整地创建/替换资源
  • 对URL进行PATCH 更新会在该客户端定义的URL上更新部分资源

PUT和POST的相关规范是RFC 2616§9.5ff。

POST创建一个子资源,因此POST到 /items 创建一个位于 /items 资源下的资源。例如。 /items/1 。两次发送相同的邮包将创建两个资源。

PUT用于在客户端已知URL处创建或替换资源。

因此:在创建资源之前,PUT仅是CREATE的候选对象,在此客户端客户已经知道该URL。例如。 /blogs/nigel/entry/when_to_use_post_vs_put 作为标题用作资源密钥

如果已存在,则PUT将替换已知URL处的资源,因此两次发送相同的请求无效。换句话说,对PUT的调用是幂等的

RFC的内容是这样的。

POST请求和PUT请求的根本区别体现在Request-URI的不同含义上。POST请求中的URI标识了将处理所附实体的资源。这个资源可能是一个数据接受过程,也可能是通向其他协议的网关,或者是接受注释的独立实体。与此相反,PUT请求中的URI标识了请求所包含的实体--用户代理知道打算使用什么URI,并且服务器不得试图将请求应用于其他资源。如果服务器希望将请求应用于不同的URI。

注意: PUT主要用于更新资源(通过整体替换资源),但是近来人们正朝着使用PATCH更新现有资源的方向发展,因为PUT指定它将替换整个资源。RFC 5789。

更新2018年:有一种情况可以避免使用PUT。请参阅“不带PUT的REST”

使用“不带PUT的REST”技术,想法是迫使消费者发布新的“统一”请求资源。如前所述,更改客户的邮寄地址是对新“ ChangeOfAddress”资源的POST,而不是具有不同邮寄地址字段值的“ Customer”资源的PUT。

摘自REST API设计-Thoughtworks的Prakash Subramaniam编写的资源建模

这就迫使API避免了多个客户端更新单个资源时的状态转换问题,并且与事件源和CQRS更加匹配。当工作是异步完成时,POST转换并等待其被应用似乎是合适的。




Answer 4 7hi4g0


Summary:

Create:

可以用PUT或POST两种方式进行,方法如下。

PUT

在/ resources URI或collection下使用newResourceId作为标识符创建THE新资源。

PUT /resources/<newResourceId> HTTP/1.1 

POST

在/ resources URI或collection下创建一个新资源。通常,标识符由服务器返回。

POST /resources HTTP/1.1

Update:

可以用下面的方式PUT进行:

PUT

在/ resources URI或collection下,以现存资源为标识更新资源。

PUT /resources/<existingResourceId> HTTP/1.1

Explanation:

当与REST和URI作为一般的处理,你有通用左边特定右侧。该仿制药通常被称为集合和更具体的项目可以被称为资源。请注意,资源可以包含集合

Examples:

<-通用-特定->

URI: website.com/users/john
website.com  - whole site
users        - collection of users
john         - item of the collection, or a resource

URI:website.com/users/john/posts/23
website.com  - whole site
users        - collection of users
john         - item of the collection, or a resource
posts        - collection of posts from john
23           - post from john with identifier 23, also a resource

当您使用POST你总是指的一个集合,所以每当你说:

POST /users HTTP/1.1

您正在向用户集合发布新用户。

如果你继续尝试这样的事情。

POST /users/john HTTP/1.1

它会起作用,但从语义上讲,您是在向用户集合下的john 集合添加资源。

使用PUT后,您将引用资源或单个项目,可能在collection中。所以当你说:

PUT /users/john HTTP/1.1

您要告诉服务器更新,或者在用户集合下创建john 资源(如果不存在)。

Spec:

让我强调一下该规范的一些重要部分。

POST

POST方法用来请求原始服务器接受封闭在请求作为实体的新下属的请求URI中使用Request-Line标识的资源的

因此,在collection上创建一个新资源

PUT

PUT将所附实体方法请求存储所提供的请求URI下。如果Request-URI引用了已经存在的资源,则应将封闭的实体视为原始服务器上的资源的修改版本。如果Request-URI 没有指向现有资源,并且请求用户代理能够将该URI 定义为资源,则原始服务器可以使用该URI 创建资源。”

因此,根据资源的存在来创建或更新。

Reference:




Answer 5 Alexander Torstling


POST 的意思是“新建”,如“此处是创建用户的输入,请为我创建”。

PUT 的意思是“插入,如果已经存在则替换”,如“此处是用户5的数据”中所述。

POST 到example.com/users,因为你不知道 URL 的用户呢,你想服务器创建它。

PUT 到example.com/users/id因为要替换/创建一个特定的用户。

使用相同数据两次发布意味着创建两个具有不同ID的相同用户。使用相同的数据两次输入将首先创建用户,第二次将其更新为相同状态(无更改)。由于无论您执行多少次 PUT 之后,您最终都会处于相同的状态,因此每次都被称为“同等效力”-幂等。这对于自动重试请求很有用。按下浏览器上的“后退”按钮时,不再“确定要重新发送”。

一般建议是,当您需要服务器控制资源的 URL 生成时,请使用 POST 。否则使用 PUT 。 与 POST 相比,首选 PUT