REST中的PUT与POST

根据HTTP/1.1规范。

POST方法用于请求源服务器接受请求中包含的实体,作为Request-LineRequest-URI标识的资源的新下级。

换句话说,POST是用来创建的。

PUT方法要求将所包含的实体存储在提供的Request-URI下。如果 "Request-URI "指的是一个已经存在的资源,所包含的实体应该被认为是驻留在源服务器上的实体的修改版本。如果 "Request-URI "没有指向现有的资源,并且该URI能够被请求的用户代理定义为新的资源,则源服务器可以用该URI创建资源。

也就是说,PUT是用来创建或更新的。

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

解决办法

总的来说:

PUT和POST都可用于创建。

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

两者都可以使用,那么我应该在我的RESTful设计中使用哪一个:

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

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

一些注意事项。

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

一个例子:

我写了以下内容,作为SO上另一个关于这个问题的答案的一部分

POST:

用来修改和更新一个资源

POST /questions/ HTTP/1.1 主机:www.example.com/

注意,以下是一个错误。

POST /questions/ HTTP/1.1 主机:www.example.com/

如果该URL尚未创建,则你 不应该使用POST来创建它 同时指定名称。 这应该 导致一个'未找到资源'的错误 因为并不存在 `gt;还不存在。 你应该把放在服务器上。 资源先放在服务器上。

不过你可以做一些事情,比如 这样用POST来创建一个资源。

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

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

PUT:

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

为一个新的资源。

PUT /questions/ HTTP/1.1 主机:www.example.com/

覆盖一个现有的资源。

PUT /questions/ HTTP/1.1 主机:www.example.com/

评论(41)

使用POST来创建,使用PUT来更新。反正Ruby on Rails就是这样做的。

PUT    /items/1      #=> update
POST   /items        #=> create
评论(8)

REST是一个非常*高层次的概念。事实上,它甚至根本就没有提到HTTP!

如果你对如何在HTTP中实现REST有任何疑问,你可以随时看看[Atom Publication Protocol(AtomPub)][1]规范。AtomPub是一个用HTTP编写RESTful webservices的标准,它是由许多HTTP和REST名人开发的,REST的发明者和HTTP的(共同)发明者Roy Fielding也提供了一些意见。

事实上,你甚至可以直接使用AtomPub。虽然它来自于博客社区,但它决不局限于博客:它是一个通用协议,用于通过HTTP与任意(嵌套)的任意资源集合进行REST式交互。如果你能把你的应用程序表示成一个资源的嵌套集合,那么你就可以直接使用AtomPub,而不必担心是否使用PUT或POST,返回什么样的HTTP状态码以及所有这些细节。

这就是AtomPub关于资源创建的内容(第9.2节)。

为了向一个集合添加成员,客户向该集合的URI发送POST请求。

评论(9)