GET、POST、PUT、PATCH、DELETE、OPTIONS、HEAD、TRACE 之間的區別(轉載至冥加)

目前互聯網公司的應用架構基本都是前後端分離,後端的接口也基本上都是採用restful架構了,接下來就說說restful的使用。
使用restful架構最主要的是遵循rest的思想:“統一資源接口“。
REST全稱:Representational State Transfer,翻譯成中文就是“表述性狀態轉移”,表述的對象就是資源,在web的rertful架構中都是通過uri來一一對應資源,比如:/api/person/1。
URI既可以看成是資源的地址,也可以看成是資源的名稱,代表的就是唯一的資源,但是不能表示對資源的操作,操作是結合標準的http方法(get、post、put等)來實現的。

下面說下restful的http方法:GET、HEAD、POST、PUT、DELETE、OPTIONS、TRACE、PATCH
根據RFC2616第九章說明,http方法的定義有兩點:safe and Idempotent,即安全性和冪等性,可以結合這兩點對以上方法進行說明

1,GET
安全、冪等;
用於獲取資源;

2,HEAD
安全、冪等;
與get方法類似,但不返回message body內容,僅僅是獲得獲取資源的部分信息(content-type、content-length);
restful框架中較少使用

3,POST
非安全、非冪等;
用於創建子資源

4,PUT
非安全、冪等;
用於創建、更新資源;

5,DELETE
非安全、冪等;
刪除資源;

6,OPTIONS
安全、冪等;
用於url驗證,驗證接口服務是否正常;

7,TEACE
安全、冪等;
維基百科“回顯服務器收到的請求,這樣客戶端可以看到(如果有)哪一些改變或者添加已經被中間服務器實現。”
restful框架中較少使用

8,PATCH
非安全、冪等;
用於創建、更新資源,於PUT類似,區別在於PATCH代表部分更新;
後來提出的接口方法,使用時可能去要驗證客戶端和服務端是否支持;

接下來說一下日常中的使用:
1,post和put的區別:

post和put的區別在於uri,或者說post用於創建子資源,比如接口:POST /api/person/  會創建一個資源比如 /api/person/1或者/api/person/2 … 或者/api/person/n,創建了新的uri,而put方法創建資源的uri是 PUT /api/person/1,這樣就創建了一個資源,如果1已經存在那麼就是更新,所以put並不是只是更新操作。再有post是非冪等的。
通常情況下,我們都會將post、get、put、delete對應到CRUD操作上,但實際上put並不是只能更新。

2,patch的使用:
patch是2010後成爲的正式http方法,詳見RFC5789,它是對put的補充,在沒有patch之前,我們都是用put進行更新操作,這時候我們的接口中通常會有一個邏輯規則,如:如果對象的的一個字符屬性爲NULL,那麼就是不更新該屬性(字段)值,如果對象的字符屬性是“”,那麼就更新該屬性(字段)的值,通過這種方式來避免全部覆蓋的操作。現在有了patch就解決了這種判斷,在put接口中不管屬性是不是null,都進行更新,在patch接口中就對非null的進行更新;

3,uri的使用問題
    上邊也介紹過了,uri即使代表資源的,通過不同的方法來區分操作,那麼像如下的接口就已經違反了restful規範:
GET /api/getPerson/1
DELETE /api/delPerson/1
GET /api/person/get/1
DELETE /api/person/delete/1
    在複合規範的前提下,uri的定義應該也是實際使用中應該考慮的,比如uri包涵那些信息?如版本、資源分類、資源名稱、表述格式等,對於設計上的不多說了,直接看下面的url:
/api/1.0/person/man/1.xml
/api/2.0/person/man/1.json
    這樣的url很常見也很直觀,對不同版本接口增加了版本信息,並且對數據的表述格式進行了顯式指定,不是不好,但是按照“統一資源接口”的思想,資源的uri已經不唯一了。有說對於版本號,表述形式等可以放到http的accept中進行指定,但具體沒有驗證過,希望經驗人士多多指教!

4,查詢問題的討論:
按照rest建議,查詢操作要使用get方法,但是實際情況中處理起來比較麻煩,如:報表統計查詢,需要傳遞的參數很多,就SpingMVC來說,如果採用get方法,那麼@RequestParam接收的參數非常多,接口很難看,通常會封裝爲java對象,希望通過@RqeustBody接收並處理,但這是不支持get方法,所以很蛋疼;
對於這種情況,最簡單的方式就是改成post方式,而且很多公司都是這麼幹的,但又覺得違反了restful規範;不改成post方式的話可能就需要將傳遞的參數對象細膩轉爲json串,後端字符串接收後再轉爲對象,這樣感覺耶不太好,url中顯式輸出參數信息,個別情況json串太長活着包含特殊字符等也都很麻煩。
希望經驗人士多多指教!


作者:冥加
來源:CSDN
原文:https://blog.csdn.net/mingjia1987/article/details/79651241
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章