2011-06-08 107 views
37

我使用Zend框架通過Zend_Rest_Route構建REST風格的api。對於文件上傳,我應該使用PUT還是POST來處理這個過程?我試圖儘可能與REST動詞的定義保持一致。請參考:PUT or POST: The REST of the StoryPUT與POST文件上傳使用Zend框架構建REST風格的API

我明白這是我應該使用,如果PUT且僅當我更新指定資源的全部內容的方式。我必須知道要輸入的確切URL。另一方面,如果我使用一些服務器端算法向服務器發送命令以創建指定資源的下級,那麼我應該使用POST。

我們假設這是一個用於圖片上傳的REST API。這是否意味着如果服務器要處理圖像文件(即創建縮略圖,調整大小等),我應該使用POST;並使用PUT,如果我只是簡單地將圖像原始文件保存到服務器?

如果我使用PUT來處理文件上傳,如果該方法是如下:

  1. 用戶發送GET請求來檢索特定的URL文件被治。
  2. 然後用戶從GET響應中發送PUT請求到URL。上傳的文件與用戶上傳完全一樣。

我對這個東西相當陌生;所以希望我在這裏有意義...

如果你知道「最好」的方式來做到這一點,隨時也可以發表評論。

回答

90

似乎有相當多的誤解在這裏。 PUT與POST不是真的關於替換與創建,而是關於冪等性和資源命名。

PUT是一個冪等操作。有了它,你可以給資源和實體的名稱放置爲資源的內容(可能是由服務器生成的添加)。最重要的是,連續執行兩次操作應該會產生相同的結果,就好像它只執行了一次或完成了20次一樣,對於「同樣的事情」的一些相當寬鬆的定義(它不一定是字節 - 字節相同,但用戶提供的信息應完好無損)。你永遠不會希望PUT導致金融交易被觸發。

POST是一個非冪等操作。您不需要提供您正在創建的資源的名稱(也不需要創建;如果需要,它可以去重複資源)。 POST通常用於實現「用新名稱創建資源並告訴我名稱是什麼」 - 「新鑄造名稱」所暗含的缺乏冪等性符合這一點。在創建新資源的情況下,發回位置標題中資源的定位符完全是正確的。現在

,如果你正在服用的是客戶應該從未創建資源名稱的政策立場,你再拿到POST是創造完美契合(雖然理論上它可以做基於提供的實體的任何東西)和PUT是如何做更新。對於很多有意義的RESTful應用程序,但不是全部;如果向用戶呈現的模型是文件系統,那麼讓用戶提供資源名稱會產生大量的意義,並且PUT將成爲主要的創建操作(並且POST將委派給不太常見的東西,比如創建空目錄等on; WebDAV甚至可以進一步減少對POST的需求)。

總結:不要以創建/更新的方式來思考,而應根據誰製作資源名稱以及哪些操作是冪等的。 PUT實際上是創建或更新的,而POST是真的做任何事情都應該被重複 - 無所畏懼。

+1

繁榮。很好的解釋,謝謝你抽出時間來充實它! – FloatingRock 2015-07-31 16:36:32

0

簡單的答案是你應該使用PUT代替POST,因爲你將會替換文件的全部內容。看看PUT vs POST

我必須知道確切的URL把 到

號你不必知道URL把即PUT URI不必存在在PUT操作之前。如果資源不存在,則創建資源。如果資源已經存在,那麼資源將被替換爲新的表示。

引述鏈接文章:

PUT在特定的URL把一個頁面。如果 那裏已經有一個頁面,那麼它就是 。如果那裏沒有頁面 ,則創建一個新頁面。這意味着 它就像刪除後 一個新的記錄與 相同主鍵

+3

從它的聲音來看,PUT非常有限。經常需要服務器端算法來操作上傳的文件。例如,對於圖像,服務器可能需要調整它們的大小。對於文檔,算法可能需要重命名它們以製作不同的版本。如果我正確理解這一點,對於PUT,它是定義資源名稱的用戶。我不確定這是否是一個好主意。 – woran 2011-06-08 02:52:56

+1

@woran:讓用戶定義資源名稱通常不是一個好主意,但不是普遍的。 (另外,您可以基於內容的散列進行版本化,以便同一內容的兩次PUT會導致一個版本,從而保留冪等性規則。) – 2013-01-18 15:55:22

3

REST插入並不是一個標準所以這很容易變成一個宗教戰爭。被認爲是「RESTful」的AtomPub和OData標準確實同意這一點:POST =創建時PUT =更新

+2

PUT和POST與REST無關。它被定義爲HTTP RFC的一部分,所以我不明白爲什麼PUT vs POST參數應該變成任何形式的爭鬥。例如, – 2011-06-08 02:44:49

+1

@Suresh,但它不知道如何:)例如,AtomPub和OData都聲稱你不能使用PUT來創建不存在的東西。這與你答案中的引用不同。 – 2011-06-08 03:01:45

+0

@Suresh,另請參閱http://stackoverflow.com/questions/630453/put-vs-post-in-rest – 2011-06-08 03:15:46