[Http] 在REST中放置與POST





PUT意味著放置一個資源 - 用一個不同的東西完全替代給定URL中的可用資源。 根據定義,PUT是冪等的。 隨心所欲地做多次,結果是一樣的。 x=5是冪等的。 無論以前是否存在資源(例如創建或更新),您都可以放入資源!

POST更新資源,添加輔助資源或導致更改。 POST不是冪等的,因為x++不是冪等的。

通過這個參數,PUT用於創建當你知道你要創建的東西的URL。 當您知道要創建的事物類別的“工廠”或經理的URL時,可以使用POST創建。


POST /expense-report


PUT  /expense-report/10929

根據HTTP / 1.1規範:

POST方法用於請求源服務器接受請求中包含的實體作為Request-Line Request-URI標識的資源的新下屬

換句話說, POST用於創建

PUT方法請求將封閉的實體存儲在提供的Request-URI 。 如果Request-URI指向一個已經存在的資源,那麼封閉的實體應該被認為是駐留在原始服務器上的修改版本。 如果Request-URI不指向現有資源,並且該URI可以被請求用戶代理定義為新資源,則源服務器可以使用該URI創建資源。“

也就是說, PUT用於創建或更新

那麼,應該使用哪一個來創建資源? 或者需要支持兩者?


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.

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 ;)

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




使用newResourceId作為標識符,在/ resources URI或集合下創建新資源。

PUT /resources/<newResourceId> HTTP/1.1 


在/ resources URI或集合下創建一個新資源。 通常這個標識符是由服務器返回的。

POST /resources HTTP/1.1



使用existingResourceId作為標識符在/ resources URI或集合下更新資源。

PUT /resources/<existingResourceId> HTTP/1.1


當將REST和URI作為一般來處理時,您的左邊通用的右邊是 具體的。 泛型通常稱為集合 ,更具體的項目可稱為資源 。 請注意, 資源可以包含一個集合


< - 通用 - 特定 - >

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

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

您正在告訴服務器更新,或者在不存在時創建該用戶 集合下的john 資源






PUT方法請求將封閉的實體存儲在提供的Request-URI下。 如果Request-URI指向一個已經存在的資源,那麼封閉的實體應該被認為是駐留在原始服務器上的修改版本 。 如果Request-URI不指向現有資源,並且該URI 可以被請求用戶代理定義為資源 ,則源服務器可以使用該URI 創建資源。“



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.

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

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.

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. That is:

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

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.

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.

REST是一個非常高層次的概念。 事實上,它甚至沒有提到HTTP!

如果您對如何在HTTP中實現REST有任何疑問,您可以隨時查看Atom發布協議(AtomPub)規範。 AtomPub是用HTTP編寫RESTful Web服務的標準,它由許多HTTP和REST開發人員開發,還有一些來自REST發明人Roy和HTTP(他自己)的發明人Roy Fielding的輸入。

事實上,你甚至可以直接使用AtomPub。 雖然它來自博客社區,但它絕不局限於博客:它是通過HTTP與任意(嵌套)任意資源集合進行REST式交互的通用協議。 如果您可以將您的應用程序表示為嵌套的資源集合,那麼您可以使用AtomPub,而不用擔心是使用PUT還是POST,需要返回哪些HTTP狀態代碼以及所有這些詳細信息。



I like this advice, from RFC 2616's definition of PUT :

The fundamental difference between the POST and PUT requests is reflected in the different meaning of the Request-URI. The URI in a POST request identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. In contrast, the URI in a PUT request identifies the entity enclosed with the request -- the user agent knows what URI is intended and the server MUST NOT attempt to apply the request to some other resource.

This jibes with the other advice here, that PUT is best applied to resources that already have a name, and POST is good for creating a new object under an existing resource (and letting the server name it).

I interpret this, and the idempotency requirements on PUT, to mean that:

  • POST is good for creating new objects under a collection (and create does not need to be idempotent)
  • PUT is good for updating existing objects (and update needs to be idempotent)
  • POST can also be used for non-idempotent updates to existing objects (especially, changing part of an object without specifying the whole thing -- if you think about it, creating a new member of a collection is actually a special case of this kind of update, from the collection's perspective)
  • PUT can also be used for create if and only if you allow the client to name the resource. But since REST clients aren't supposed to make assumptions about URL structure, this is less in the intended spirit of things.

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.





使用相同的數據發布兩次表示使用不同的ID創建兩個相同的用戶。 使用相同的數據進行兩次創建,創建用戶第一次,並在第二次將其更新為同一狀態(不更改)。 由於無論你執行多少次PUT,你最終都會得到相同的狀態,所以每次都說它“同樣有效” - 冪等性的。 這對於自動重試請求很有用。 當您按下瀏覽器上的後退按鈕時,沒有更多'您確定要重新發送'。

一般建議是在需要服務器控制資源的URL生成時使用POST。 否則使用PUT。 在POST上優先使用PUT。

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.