在REST中放置与POST

根据HTTP / 1.1规范:

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

换句话说, POST被用来创build

PUT方法要求封闭的实体存储在提供的Request-URI 。 如果Request-URI引用一个已经存在的资源,封闭的实体应该被认为是驻留在原始服务器上的修改版本。 如果Request-URI不指向现有资源,并且该URI可以被请求用户代理定义为新资源,则源服务器可以使用该URI创build资源。

也就是说, PUT被用来创build或更新

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

总体:

PUT和POST都可以用于创build。

你必须问“你在做什么?” 区分你应该使用什么。 假设您正在devise一个提问问题的API。 如果你想使用POST,那么你会这样做的问题列表。 如果你想使用PUT,那么你会这样做到一个特定的问题。

好的都可以使用,所以我应该在我的RESTfuldevise中使用哪一个:

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

使用哪个是留给你的。 但是请记住根据您在请求中引用的对象来使用正确的对象。

一些考虑:

  • 你是否明确指定了你创build的URL对象,或者让服务器决定? 如果你命名他们,然后使用PUT。 如果你让服务器决定,然后使用POST。
  • PUT是幂等的,所以如果你把一个对象放两次,它就不起作用。 这是一个很好的属性,所以我会尽可能使用PUT。
  • 您可以使用相同的对象URL更新或创buildPUT资源
  • 通过POST,您可以同时对2个请求进行修改,并且可以更新对象的不同部分。

一个例子:

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

POST:

用于修改和更新资源

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

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

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

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

你可以做这样的事情来使用POST创build一个资源:

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

请注意,在这种情况下,资源名称未指定,新的对象URLpath将返回给您。

放:

用于创build资源或覆盖它。 当你指定资源新的URL。

对于新资源:

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

要覆盖现有资源:

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

你可以在网上find断言

  • POST应该被用来创build一个资源,并且PUT应该被用来修改一个
  • 应该使用PUT来创build一个资源,并且应该使用POST来修改一个资源

这两个都不对。


更好的是基于动作的幂等性在PUT和POST之间进行select。

PUT意味着要放置一个资源 – 用一个不同的东西来完全replace给定URL中的可用资源。 根据定义,PUT是幂等的。 按照你喜欢的次数来做,结果是一样的。 x=5是幂等的。 你可以放弃一个资源,不pipe它以前是否存在(例如创build或更新)!

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


通过这个参数,PUT用于创build当你知道你将创build的东西的URL。 POST可用于在知道要创build的事物类别的“工厂”或pipe理器的URL时创build。

所以:

 POST /expense-report 

要么:

 PUT /expense-report/10929 
  • POST到URL 服务器定义的 URL处创build一个子资源
  • PUT到URL在客户端定义的 URL处创build/replace整个资源
  • PATCH到一个URL 更新该客户端定义的URL 的资源的一部分

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

POST创build一个子资源 ,所以POST到/items创build一个资源,位于/items资源下。 例如。 /items/1 。 两次发送相同的post数据包将创build两个资源。

PUT用于在客户端已知URL处创build或replace资源。

因此: PUT只是在创build资源之前客户端已经知道url的CREATE候选者。 例如。 /blogs/nigel/entry/when_to_use_post_vs_put作为标题被用作资源键

如果已知的URL已经存在, PUT将replace资源,因此两次发送相同的请求不起作用。 换句话说, 对PUT的调用是幂等的

RFC的读法是这样的:

POST和PUT请求之间的根本区别反映在Request-URI的不同含义中。 POST请求中的URI标识将处理封闭实体的资源。 该资源可能是数据接受过程,某个其他协议的入口,也可能是接受注释的单独实体。 相比之下,PUT请求中的URI标识了请求所包含的实体 – 用户代理知道哪个URI是预期的,服务器不能尝试将请求应用到其他资源。 如果服务器希望将请求应用于不同的URI,

注意: PUT主要用于更新资源(通过全部replace它们),但是最近有一种趋势是使用PATCH来更新现有资源,因为PUT指定replace整个资源。 RFC 5789。

我想补充我的“务实”的build议。 当您知道您正在保存的对象的“id”可以被检索时使用PUT。 如果你需要(比方说,一个数据库生成的id)被返回给你做未来的查找或更新,使用PUT将不会工作得太好。

所以:要保存一个现有的用户,或者一个客户端生成id的地方,并且validation了id是唯一的:

 PUT /user/12345 HTTP/1.1 <-- create the user providing the id 12345 Host: mydomain.com GET /user/12345 HTTP/1.1 <-- return that user Host: mydomain.com 

否则,使用POST来初始创build对象,并使用PUT来更新对象:

 POST /user HTTP/1.1 <--- create the user, server returns 12345 Host: mydomain.com PUT /user/12345 HTTP/1.1 <--- update the user Host: mydomain.com 

概要:

创build:

可以用以下方式同时执行PUT或POST:

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

 PUT /resources/<newResourceId> HTTP/1.1 

POST

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

 POST /resources HTTP/1.1 

更新:

只能用以下方式执行PUT:

使用existingResourceId作为标识符,在/ resources URI或集合下更新资源。

 PUT /resources/<existingResourceId> HTTP/1.1 

说明:

在处理REST和URI时,通常在左边通用的右边是 具体的。 generics通常称为集合 ,更具体的项目可称为资源 。 请注意, 资源可以包含一个集合

例子:

< – generic – specific – >

 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,你可能在一个集合中引用一个资源或单个项目。 所以当你说:

 PUT /users/john HTTP/1.1 

您正在告诉服务器更新,或者如果它不存在,请创build用户 集合下的john 资源

规格:

让我强调规范的一些重要部分:

POST

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

因此,创build一个集合的新资源

PUT方法要求封闭的实体存储在提供的Request-URI下。 如果Request-URI引用一个已经存在的资源,封闭的实体应该被认为是驻留在原始服务器上的修改版本 。 如果Request-URI不指向现有资源,并且该URI 可以被请求用户代理定义为资源 ,则源服务器可以使用该URI 创build资源。

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

参考:

  • HTTP / 1.1规范
  • 维基百科 – REST
  • 统一资源标识符(URI):通用语法和语义

POST的意思是“创build新的”,如“这是创build用户的input,为我创build”。

PUT的意思是“插入,replace,如果已经存在”,如“这是用户5的数据”。

由于您还不知道用户的URL,因此您要通过example.com/users进行POST,您希望服务器创build它。

由于您想要replace/创build特定的用户,因此您需要inputexample.com/users/id。

使用相同的数据发布两次表示使用不同的ID创build两个相同的用户。 使用相同的数据进行两次创build,创build第一个用户,并在第二次将其更新为同一状态(不更改)。 既然你在PUT之后结束了同样的状态,不pipe你执行了多less次,它都被认为是“同样有效的”,每次都是幂等的。 这对自动重试请求很有用。 当您按下浏览器上的后退button时,不再确定要重新发送。

一般的build议是在需要服务器控制资源的URL生成时使用POST。 否则使用PUT。 优先于POST的PUT。

使用POST来创build,然后PUT来更新。 无论如何,Ruby on Rails就是这样做的。

 PUT /items/1 #=> update POST /items #=> create 

REST是一个非常高层次的概念。 事实上,它甚至不提及HTTP!

如果您对如何在HTTP中实现REST有任何疑问,可以随时查看Atom发布协议(AtomPub)规范。 AtomPub是用HTTP编写RESTful Web服务的标准,由许多HTTP和REST开发人员开发,还有一些来自REST的发明者Roy和HTTP的发明人Roy Fielding。

实际上,你甚至可以直接使用AtomPub。 虽然它来自博客社区,但它绝不限于博客:它是通过HTTP与任意(嵌套)任意资源集合进行REST式交互的通用协议。 如果您可以将您的应用程序表示为资源的嵌套集合,那么您可以使用AtomPub,而不用担心是否使用PUT或POST,返回哪些HTTP状态代码以及所有这些详细信息。

这就是AtomPub关于资源创build的说法 :

要将成员添加到Collection,客户端将POST请求发送到Collection的URI。

我喜欢这个build议,从RFC 2616的定义PUT :

POST和PUT请求之间的根本区别反映在Request-URI的不同含义中。 POST请求中的URI标识将处理封闭实体的资源。 该资源可能是数据接受过程,某个其他协议的入口,也可能是接受注释的单独实体。 相比之下,PUT请求中的URI标识了请求所包含的实体 – 用户代理知道哪个URI是预期的,服务器不能尝试将请求应用到其他资源。

这与此处的其他build议一致,PUT最适用于已有名称的资源,POST适用于在现有资源下创build新对象(并让服务器命名它)。

我解释这一点,以及对PUT的幂等要求意味着:

  • POST很适合在集合下创build新对象(并且创build不需要是幂等的)
  • PUT适用于更新现有对象(更新需要是幂等的)
  • POST也可以用于对现有对象进行非幂等更新(特别是在不指定整个对象的情况下更改对象的一部分 – 如果考虑到这一点,创build一个集合的新成员实际上是这种types的特殊情况更新,从收集的angular度来看)
  • PUT也可用于创build当且仅当您允许客户端命名资源。 但是,由于REST客户端不应该对URL结构做出假设,所以在本意的精神上就不那么重要了。

是否使用PUT或POST在具有HTTP + REST API的服务器上创build资源的决定取决于谁拥有URL结构。 让客户知道或参与定义URL结构是一种不必要的耦合,类似于SOA产生的不需要的耦合。 逃生types的联轴器是REST如此受欢迎的原因。 因此, 正确的使用方法是POST。 这个规则也有例外,当客户希望保留对所部署资源的位置结构的控制权时,就会发生这种情况。 这是罕见的,可能意味着别的是错的。

在这一点上,有些人会争辩说,如果使用RESTful-URL ,客户端确实知道资源的URL,因此PUT是可以接受的。 毕竟,这就是为什么规范的,标准化的,Ruby on Rails,Django的URL是重要的,看看Twitter的API …等等等等等等等等等等等等等等等。 那些人需要明白,没有像Restful-URL这样的东西 ,而且Roy Fielding自己说

REST API不能定义固定的资源名称或层次结构(客户端和服务器明显的耦合)。 服务器必须有自由来控制自己的命名空间。 相反,允许服务器通过在媒体types和链接关系中定义这些指令来指导客户如何构build适当的URI,例如在HTML表单和URI模板中完成。 [这里的失败意味着客户端由于带外信息(例如特定于领域的标准,这是面向数据的RPC等效于RPC的function耦合)正在假设资源结构)。

http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

RESTful-URL的概念实际上是对REST的违反,因为服务器负责URL结构,应该可以自由决定如何使用它来避免耦合。 如果这让你感到困惑,请阅读关于APIdevise上自我发现的意义。

由于POST不是幂等的,因此使用POST创build资源需要考虑devise。 这意味着多次重复POST不能保证每次都有相同的行为。 这让人们害怕使用PUT来创build资源。 他们知道这是错误的(POST是针对CREATE的),但他们这样做,因为他们不知道如何解决这个问题。 这种担忧在以下情况下得到certificate:

  1. 客户端将新资源发布到服务器。
  2. 服务器处理请求并发送响应。
  3. 客户永远不会收到回应。
  4. 服务器不知道客户端没有收到响应。
  5. 客户端没有资源的URL(因此PUT不是一个选项)并重复POST。
  6. POST不是幂等的,服务器…

步骤6是人们通常对做什么感到困惑的地方。 但是,没有理由创build一个kludge来解决这个问题。 相反,可以按照RFC 2616中的规定使用HTTP,服务器将回复:

10.4.10 409冲突

由于与当前资源状态的冲突,请求无法完成。 此代码仅在预期用户可能能够解决冲突并重新提交请求的情况下才被允许。 响应主体应该包括足够的

信息供用户识别冲突的来源。 理想情况下,响应实体会为用户或用户代理提供足够的信息来解决问题; 然而,这可能是不可能的,也不是必需的。

冲突最有可能发生在响应PUT请求。 例如,如果正在使用版本控制,并且包含PUT的实体更改为与先前(第三方)请求相冲突的资源,则服务器可能会使用409响应来指示无法完成请求。 在这种情况下,响应实体可能会以响应Content-Type定义的格式包含两个版本之间的差异列表。

回复状态代码409冲突是正确的方法,因为

  • 执行具有与系统中已有资源匹配的ID的数据的POST是“与资源的当前状态冲突”。
  • 由于重要的部分是让客户端了解服务器有资源并采取适当的行动。 这是一个“预期用户可能能够解决冲突并重新提交请求的情况”。
  • 包含具有冲突ID的资源的URL和资源的适当先决条件的响应将提供“足够的信息给用户或用户代理来解决问题”,这是根据RFC 2616的理想情况。

根据RFC 7231的发布更新到replace2616

RFC 7231的目的是取代2616,并在4.3.3节描述了对POST的可能的响应

如果处理POST的结果等同于现有资源的表示,则原始服务器可以通过使用位置字段中的现有资源标识符发送303(参见其他)响应来将用户代理redirect到该资源。 这具有为用户代理提供资源标识符并通过更适合于共享caching的方法传送表示的益处,尽pipe如果用户代理尚未具有caching的表示,则以额外请求为代价。

现在可能很容易在POST重复的情况下返回303。 但是,情况正好相反。 Returning a 303 would only make sense if multiple create requests (creating different resources) return the same content. An example would be a "thank you for submitting your request message" that the client need not re-download each time. RFC 7231 still maintains in section 4.2.2 that POST is not to be idempotent and continues to maintain that POST should be used for create.

For more information about this, read this article .

POST is like posting a letter to a mailbox or posting an email to an email queue. PUT is like when you put an object in a cubby hole or a place on a shelf (it has a known address).

With POST, you're posting to the address of the QUEUE or COLLECTION. With PUT, you're putting to the address of the ITEM.

PUT is idempotent. You can send the request 100 times and it will not matter. POST is not idempotent. If you send the request 100 times, you'll get 100 emails or 100 letters in your postal box.

A general rule: if you know the id or name of the item, use PUT. If you want the id or name of the item to be assigned by the receiving party, use POST.

POST versus PUT

New answer (now that I understand REST better):

PUT is merely a statement of what content the service should, from now on, use to render representations of the resource identified by the client; POST is a statement of what content the service should, from now on, contain (possibly duplicated) but it's up to the server how to identify that content.

PUT x (if x identifies a resource ): "Replace the content of the resource identified by x with my content."

PUT x (if x does not identify a resource): "Create a new resource containing my content and use x to identify it."

POST x : "Store my content and give me an identifier that I can use to identify a resource (old or new) containing said content (possibly mixed with other content). Said resource should be identical or subordinate to that which x identifies." " y 's resource is subordinate to x 's resource" is typically but not necessarily implemented by making y a subpath of x (eg x = /foo and y = /foo/bar ) and modifying the representation(s) of x 's resource to reflect the existence of a new resource, eg with a hyperlink to y 's resource and some metadata. Only the latter is really essential to good design, as URLs are opaque in REST — you're supposed to use hypermedia instead of client-side URL construction to traverse the service anyways.

In REST, there's no such thing as a resource containing "content". I refer as "content" to data that the service uses to render representations consistently. It typically consists of some related rows in a database or a file (eg an image file). It's up to the service to convert the user's content into something the service can use, eg converting a JSON payload into SQL statements.

Original answer (might be easier to read) :

PUT /something (if /something already exists): "Take whatever you have at /something and replace it with what I give you."

PUT /something (if /something does not already exist): "Take what I give you and put it at /something ."

POST /something : "Take what I give you and put it anywhere you want under /something as long as you give me its URL when you're done."

Ruby on Rails 4.0 will use the 'PATCH' method instead of PUT to do partial updates.

RFC 5789 says about PATCH (since 1995):

A new method is necessary to improve interoperability and prevent errors. The PUT method is already defined to overwrite a resource with a complete new body, and cannot be reused to do partial changes. Otherwise, proxies and caches, and even clients and servers, may get confused as to the result of the operation. POST is already used but without broad interoperability (for one, there is no standard way to discover patch format support). PATCH was mentioned in earlier HTTP specifications, but not completely defined.

" Edge Rails: PATCH is the new primary HTTP method for updates " explains it.

简而言之:

PUT is idempotent, where the resource state will be the same if the same operation is executed one time or multiple times.

POST is non-idempotent, where the resource state may become different if the operation is executed multiple times as compared to executing a single time.

Analogy with database query

PUT You can think of similar to "UPDATE STUDENT SET address = "abc" where id="123";

POST You can think of something like "INSERT INTO STUDENT(name, address) VALUES ("abc", "xyzzz");

Student Id is auto generated.

With PUT, if the same query is executed multiple times or one time, the STUDENT table state remains the same.

In case of POST, if the same query is executed multiple times then multiple Student records get created in the database and the database state changes on each execution of an "INSERT" query.

NOTE: PUT needs a resource location (already-resource) on which update needs to happen, whereas POST doesn't require that. Therefore intuitively POST is meant for creation of a new resource, whereas PUT is needed for updating the already existing resource.

Some may come up with that updates can be performed with POST. There is no hard rule which one to use for updates or which one to use for create. Again these are conventions, and intuitively I'm inclined with the above mentioned reasoning and follow it.

Both are used for data transmission between client to server, but there are subtle differences between them, which are:

在这里输入图像说明

At the risk of restating what has already been said, it seems important to remember that PUT implies that the client controls what the URL is going to end up being, when creating a resource. So part of the choice between PUT and POST is going to be about how much you can trust the client to provide correct, normalized URL that are coherent with whatever your URL scheme is.

When you can't fully trust the client to do the right thing, it would be more appropriate to use POST to create a new item and then send the URL back to the client in the response.

The most important consideration is reliability . If a POST message gets lost the state of the system is undefined. Automatic recovery is impossible. For PUT messages, the state is undefined only until the first successful retry.

For instance, it may not be a good idea to create credit card transactions with POST.

If you happen to have auto generated URI's on your resource you can still use PUT by passing a generated URI (pointing to an empty resource) to the client.

Some other considerations:

  • POST invalidates cached copies of the entire containing resource (better consistency)
  • PUT responses are not cacheable while POST ones are (Require Content-Location and expiration)
  • PUT is less supported by eg Java ME, older browsers, firewalls

the origin server can create the resource with that URI

So you use POST and probably, but not necessary PUT for resource creation. You don't have to support both. For me POST is perfectly enough. So it is a design decision.

As your quote mentioned, you use PUT for creation of there is no resource assigned to an IRI, and you want to create a resource anyway. For example, PUT /users/123/password usually replaces the old password with a new one, but you can use it to create a password if it does not exist already (for example, by freshly registered users or by restoring banned users).

There seems to always be some confusion as to when to use the HTTP POST versus the HTTP PUT method for REST services. Most developers will try to associate CRUD operations directly to HTTP methods. I will argue that this is not correct and one can not simply associate the CRUD concepts to the HTTP methods. 那是:

 Create => HTTP PUT Retrieve => HTTP GET Update => HTTP POST Delete => HTTP DELETE 

It is true that the R(etrieve) and D(elete) of the CRUD operations can be mapped directly to the HTTP methods GET and DELETE respectively. However, the confusion lies in the C(reate) and U(update) operations. In some cases, one can use the PUT for a create while in other cases a POST will be required. The ambiguity lies in the definition of an HTTP PUT method versus an HTTP POST method.

According to the HTTP 1.1 specifications the GET, HEAD, DELETE, and PUT methods must be idempotent, and the POST method is not idempotent. That is to say that an operation is idempotent if it can be performed on a resource once or many times and always return the same state of that resource. Whereas a non idempotent operation can return a modified state of the resource from one request to another. Hence, in a non idempotent operation, there is no guarantee that one will receive the same state of a resource.

Based on the above idempotent definition, my take on using the HTTP PUT method versus using the HTTP POST method for REST services is: Use the HTTP PUT method when:

 The client includes all aspect of the resource including the unique identifier to uniquely identify the resource. Example: creating a new employee. The client provides all the information for a resource to be able to modify that resource.This implies that the server side does not update any aspect of the resource (such as an update date). 

In both cases, these operations can be performed multiple times with the same results. That is the resource will not be changed by requesting the operation more than once. Hence, a true idempotent operation. Use the HTTP POST method when:

 The server will provide some information concerning the newly created resource. For example, take a logging system. A new entry in the log will most likely have a numbering scheme which is determined on the server side. Upon creating a new log entry, the new sequence number will be determined by the server and not by the client. On a modification of a resource, the server will provide such information as a resource state or an update date. Again in this case not all information was provided by the client and the resource will be changing from one modification request to the next. Hence a non idempotent operation. 

结论

Do not directly correlate and map CRUD operations to HTTP methods for REST services. The use of an HTTP PUT method versus an HTTP POST method should be based on the idempotent aspect of that operation. That is, if the operation is idempotent, then use the HTTP PUT method. If the operation is non idempotent, then use the HTTP POST method.

The semantics are supposed be different, in that "PUT", like "GET" is supposed to be idempotent — meaning, you can the same exact PUT request multiple times and the result will be as if you executed it only once.

I will describe the conventions which I think are most widely used and are most useful:

When you PUT a resource at a particular URL what happens is that it should get saved at that URL, or something along those lines.

When you POST to a resource at a particular URL, often you are posting a related piece of information to that URL. This implies that the resource at the URL already exists.

For example, when you want to create a new stream, you can PUT it to some URL. But when you want to POST a message to an existing stream, you POST to its URL.

As for modifying the properties of the stream, you can do that with either PUT or POST. Basically, only use "PUT" when the operation is idempotent – otherwise use POST.

Note, however, that not all modern browsers support HTTP verbs other than GET or POST.

I'm going to land with the following:

PUT refers to a resource, identified by the URI. In this case, you are updating it. It is the part of the three verbs referring to resources — delete and get being the other two.

POST is basically a free form message, with its meaning being defined 'out of band'. If the message can be interpreted as adding a resource to a directory, that would be OK, but basically you need to understand the message you are sending (posting) to know what will happen with the resource.


Because PUT and GET and DELETE refer to a resource, they are also by definition idempotent.

POST can perform the other three functions, but then the semantics of the request will be lost on the intermediaries such as caches and proxies. This also applies to providing security on the resource, since a post's URI doesn't necessarily indicate the resource it is applying to (it can though).

A PUT doesn't need to be a create; the service could error if the resource isn't already created, but otherwise update it. Or vice versa — it may create the resource, but not allow updates. The only thing required about PUT is that it points to a specific resource, and its payload is the representation of that resource. A successful PUT means (barring interference) that a GET would retrieve the same resource.


Edit: One more thing — a PUT can create, but if it does then the ID has to be a natural ID — AKA an email address. That way when you PUT twice, the second put is an update of the first. This makes it idempotent .

If the ID is generated (a new employee ID, for example), then the second PUT with the same URL would create a new record, which violates the idempotent rule. In this case the verb would be POST, and the message (not resource) would be to create a resource using the values defined in this message.

In a very simple way I'm taking the example of the Facebook timeline.

Case 1: When you post something on your timeline, it's a fresh new entry. So in this case they use the POST method because the POST method is non-idempotent.

Case 2: If your friend comment on your post the first time, that also will create a new entry in the database so the POST method used.

Case 3: If your friend edits his comment, in this case, they had a comment id, so they will update an existing comment instead of creating a new entry in the database. Therefore for this type of operation use the PUT method because it is idempotent.*

In a single line, use POST to add a new entry in the database and PUT to update something in the database.

While there is probably an agnostic way to describe these, it does seem to be conflicting with various statements from answers to websites.

Let's be very clear and direct here. If you are a .NET developer working with Web API, the facts are (from the Microsoft API documentation), http://www.asp.net/web-api/overview/creating-web-apis/creating-a-web-api-that-supports-crud-operations :

 1. PUT = UPDATE (/api/products/id) 2. MCSD Exams 2014 - UPDATE = PUT, there are **NO** multiple answers for that question period. 

Sure you "can" use "POST" to update, but just follow the conventions laid out for you with your given framework. In my case it is .NET / Web API, so PUT is for UPDATE there is no debate.

I hope this helps any Microsoft developers that read all comments with Amazon and Sun/Java website links.

If you are familiar with database operations, there are

  1. select
  2. 更新
  3. 删除
  4. Merge (Update if already existing, else insert)

I use PUT for Merge and update like operations and use POST for Insertions.

Most of the time, you will use them like this:

  • POST a resource into a collection
  • PUT a resource identified by collection/:id

例如:

  • POST /items
  • PUT /items/1234

In both cases, the request body contains the data for the resource to be created or updated. It should be obvious from the route names that POST is not idempotent (if you call it 3 times it will create 3 objects), but PUT is idempotent (if you call it 3 times the result is the same). PUT is often used for "upsert" operation (create or update), but you can always return a 404 error if you only want to use it to modify.

Note that POST "creates" a new element in the collection, and PUT "replaces" an element at a given URL, but it is a very common practice to use PUT for partial modifications, that is, use it only to update existing resources and only modify the included fields in the body (ignoring the other fields). This is technically incorrect, if you want to be REST-purist, PUT should replace the whole resource and you should use PATCH for the partial update. I personally don't care much as far as the behavior is clear and consistent across all your API endpoints.

Remember, REST is a set of conventions and guidelines to keep your API simple. If you end up with a complicated work-around just to check the "RESTfull" box then you are defeating the purpose 😉

In practice, POST works well for creating resources. The URL of the newly created resource should be returned in the Location response header. PUT should be used for updating a resource completely. Please understand that these are the best practices when designing a RESTful API. HTTP specification as such does not restrict using PUT/POST with a few restrictions for creating/updating resources. Take a look at http://techoctave.com/c7/posts/71-twitter-rest-api-dissected that summarizes the best practices.

Here's a simple rule:

PUT to a URL should be used to update or create the resource that can be located at that URL.

POST to a URL should be used to update or create a resource which is located at some other ("subordinate") URL, or is not locatable via HTTP.

Readers new to this topic will be struck by the endless discussion about what you should do, and the relative absence of lessons from experience. The fact that REST is "preferred" over SOAP is, I suppose, a high-level learning from experience, but goodness we must have progressed from there? It's 2016. Roy's dissertation was in 2000. What have we developed? Was it fun? Was it easy to integrate with? To support? Will it handle the rise of smartphones and flaky mobile connections?

According to ME, real-life networks are unreliable. Requests timeout. Connections are reset. Networks go down for hours or days at a time. Trains go into tunnels with mobile users aboard. For any given request (as occasionally acknowledged in all this discussion) the request can fall in the water on its way, or the response can fall in the water on its way back. In these conditions, issuing PUT, POST and DELETE requests directly against substantive resources has always struck me as a little brutal and naive.

HTTP does nothing to ensure reliable completion of the request-response, and that's just fine because this is properly the job of network-aware applications. Developing such an application, you can jump through hoops to use PUT instead of POST, then more hoops to give a certain kind of error on the server if you detect duplicate requests. Back at the client, you then have to jump through hoops to interpret these errors, refetch, revalidate and repost.

Or you can do this : consider your unsafe requests (actions) as ephemeral single-user resources. Clients request a new "action" on a substantive resource with an empty POST to the resource. POST will be used only for this. Once safely in possession of the URI of the freshly minted action, the client PUTs the unsafe request to the action URI, not the target resource . Resolving the action and updating the "real" resource is properly the job of your API, and is here decoupled from the unreliable network.

The server does the business, returns the response and stores it against the agreed action URI . If anything goes wrong, the client repeats the request (natural behaviour!), and if the server has already seen it, it repeats the stored response and does nothing else .

You will quickly spot the similarity with promises: we create and return the placeholder for the result before doing anything. Also like a promise, an action can succeed or fail one time, but its result can be fetched repeatedly.

Best of all, we give sending and receiving applications a chance to link the uniquely identified action to uniqueness in their respective environments. And we can start to demand, and enforce!, responsible behaviour from clients: repeat your requests as much as you like, but don't go generating a new action until you're in possession of a definitive result from the existing one.

As such, numerous thorny problems go away. Repeated insert requests won't create duplicates, and we don't create the real resource until we're in possession of the data. (database columns can stay not-nullable). Repeated update requests won't hit incompatible states and won't overwrite subsequent changes. Clients can (re)fetch and seamlessy process the original confirmation for whatever reason (client crashed, response went missing, etc.).

Successive delete requests can see and process the original confirmation, without hitting a 404 error. If things take longer than expected, we can respond provisionally, and we have a place where the client can check back for the definitive result. The nicest part of this pattern is its Kung-Fu (Panda) property. We take a weakness, the propensity for clients to repeat a request any time they don't understand the response, and turn it into a strength 🙂

Before telling me this is not RESTful, please consider the numerous ways in which REST principles are respected. Clients don't construct URLs. The API stays discoverable, albeit with a little change in semantics. HTTP verbs are used appropriately. If you think this is a huge change to implement, I can tell you from experience that it's not.

If you think you'll have huge amounts of data to store, let's talk volumes: a typical update confirmation is a fraction of a kilobyte. HTTP currently gives you a minute or two to respond definitively. Even if you only store actions for a week, clients have ample chance to catch up. If you have very high volumes, you may want a dedicated acid-compliant key value store, or an in-memory solution. If you still need convincing, I have a little Google Docs document here .

POST: Use it for creating new resources. It's like INSERT (SQL statement) with an auto-incremented ID. In the response part it contains a new generated Id.

POST is also used for updating a record.

PUT: Use it for creating a new resource, but here I know the identity key. It's like INSERT (SQL statement) where I know in advance the identity key. In the response part it sends nothing.

PUT is also used for updating a resource

简答:

Simple rule of thumb: Use POST to create, use PUT to update.

Long Answer:

POST:

  • POST is used to send data to server.
  • Useful when the resource's URL is unknown

PUT:

  • PUT is used to transfer state to the server
  • Useful when a resource's URL is known

Longer Answer:

To understand it we need to question why PUT was required, what were the problems PUT was trying to solve that POST couldn't.

From a REST architecture's point of view there is none that matters. We could have lived without PUT as well. But from a client developer's point of view it made his/her life a lot simpler.

Prior to PUT, clients couldn't directly know the URL that the server generated or if all it had generated any or whether the data to be sent to the server is already updated or not. PUT relieved the developer of all these headaches. PUT is idempotent, PUT handles race conditions, and PUT lets the client choose the URL.