冪等性的含義和 HTTP請求方法的冪等性
1、什么是冪等性
===============
冪等性,英文是idempotent,讀作[aɪ'dɛmpətənt]。
它的含義如下:
“Methods can also have the property of "idempotence" in that the side-effects of N > 0 identical requests is the same as for a single request.”(這句話翻譯過來是這樣的:方法可以有冪等性,冪等性指的是N>0次的完全相同的請求的副作用和一次單個請求的副作用是相同的)。
即,如果一個方法重復執行多次,產生的效果是一樣的,那么這個方法就是冪等的。
2、HTTP請求方法的冪等性
=====================
方法名 | 作用 | 安全性 | 冪等性 |
DELETE | 刪除資源,冪等操作 | 否 | 是 |
POST | 新增資源,非冪等操作 | 否 | 否 |
GET | 查詢資源,冪等操作 | 是 | 是 |
PUT | 更新資源,冪等操作 | 否 | 是 |
PATCH | 更新資源,非冪等操作 | 否 | 否 |
HEAD | 類似於GET請求,只不過返回的響應中沒有具體的內容,用於獲取報頭 | 是 | 是 |
OPTIONS | 用於客戶端查看服務器的性能 | 是 | 是 |
3、請求方法的語義辨析
===================
3.1 put和post的區別
------------------------------
有的觀點認為,應該用POST來創建一個資源,用PUT來更新一個資源;有的觀點認為,應該用PUT來創建一個資源,用POST來更新一個資源;還有的觀點認為可以用PUT和POST中任何一個來做創建或者更新一個資源。這些觀點都只看到了風格,爭論起來也只是爭論哪種風格更好,其實,用PUT還是POST,不是看這是創建還是更新資源的動作,這不是風格的問題,而是語義的問題。
在HTTP中,PUT被定義為idempotent的方法,而POST則不是冪等的,這是一個它們在語義上的最重要的區別。
舉一個例子,假如有一個博客系統提供一個Restful API,模式是這樣http://superblogging/blogs/{blog-name}。當往這個URI發送一個HTTP PUT或者POST請求時,博文會存放在http request body部分發送給服務器端。
此時,這個請求應該用PUT方法還是POST方法呢?這取決於這個REST服務的行為是否是冪等的。
假如客戶端發送兩個http://superblogging/blogs/Sample請求,服務器端產生了兩個文章內容一樣的博客,那就說明這個服務不是冪等的,因為多次調用產生了多個結果,而不是多次調用只產生一個結果。
如果第二個請求把第一個請求給覆蓋掉了,那這個服務就是冪等的。
前一種情況,應該使用POST方法,后一種情況,應該使用PUT方法。
3.2 為什么patch是非冪等的
-------------------------------------
PUT方法的實體無結構的,它直接把實體部分的數據替換到服務器的資源上。而PATCH提供的實體則需要根據程序或其它協議的定義,解析后在服務器上執行,以此來修改服務器上的數據。也就是說,PATCH請求是會執行某個程序的,如果重復提交,程序可能執行多次,對服務器上的資源就可能造成額外的影響,這就可以解釋它為什么是不冪等的了。
舉個例子,如果服務器上有個資源/abc.int,里面存放一個整數,值為 1。當GET這個資源的時候,服務器響應的實體只包含了 1 這個數字。現在在自己的框架中定義當提交PATCH請求,實體匹配^\+\d+$的格式時就對服務器資源中的數字執行一個加法操作。於是當客戶端向/abc.int地址發起PATCH請求,實體部分為+3之后,服務器的/abc.int資源中的數據就變成 4,也就是說,GET它會得到 4。如果客戶端不小心重復提交了PATCH請求,那么+3就會被再執行一次,這個資源的數據就變成 7。從這個例子可以看出,PATCH請求會對資源進行修改,請求一次修改一次,多次請求多次修改,每次修改之后資源的狀態都會改變,這就是為什么說PATCH方法是非冪等的了。
參考資料
1、http://www.cnblogs.com/jinks/p/3511282.html http請求方法的安全性和冪等性
2、http://www.cnblogs.com/yin-jingyu/archive/2011/08/01/2123548.html http協議的說明
3、http://www.jianshu.com/p/178da1e2903c