為什么會出現(xiàn)RESTful
先不要急著知道RESTful到底是什么,它沒那么高深的吴攒。要想清楚的知道RESTful肖粮,首先回顧下HTTP協(xié)議,以及API(Application Programming Interface,應(yīng)用程序編程接口)丛晦。這樣可以知道RESTful的來歷及意義所在奕纫。
-
API
應(yīng)用程序編程接口,說白了就是預(yù)定義一些功能烫沙,供其他調(diào)用匹层,從而做到提供服務(wù)的作用。
- HTTP
在這里不說具體HTTP的含義锌蓄,及相關(guān)基礎(chǔ)的概念升筏。想了解可以參考《圖解HTTP》這本書仲器,講的很詳細也很生動。在這里只想說說HTTP協(xié)議的基本構(gòu)成仰冠。
HTTP協(xié)議工作于客戶端-服務(wù)端架構(gòu)為上乏冀。瀏覽器作為HTTP客戶端通過URL向HTTP服務(wù)端即WEB服務(wù)器發(fā)送所有請求。Web服務(wù)器根據(jù)接收到的請求后洋只,向客戶端發(fā)送響應(yīng)信息辆沦。這里就涉及到HTTP請求Request)和響應(yīng)(Response),對于一個完整的請求(Request)识虚、響應(yīng)(Response)來說肢扯,還是有一定規(guī)范的(有套路的),這里我們看一下HTTP請求和響應(yīng)的一些基本信息担锤。
舉個栗子:
我們用Fiddler抓了一下360瀏覽器的任務(wù)中心的API接口信息蔚晨,如下是它的請求信息:
GET http://task.browser.#/online/setpoint HTTP/1.1
Accept: */*
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Pragma: no-cache
Content-Type: application/x-www-form-urlencoded
Host: task.browser.#
Content-Length: 449
Cookie:__guid=91251416.3523784108665864700.1520256100246.427D%25PO%25QR%25P9%25R1%25P0%25RS%25O5%25P4%25PO%25N7%25
得到的服務(wù)器響應(yīng)結(jié)果,如下所示:
```
HTTP/1.1 200 OK
Server: nginx/1.6.3
Date: Sat, 10 Mar 2018 03:37:00 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: close
{"errno":"10003","errmsg":"\u7b7e\u540d\u9519\u8bef"}
```
我們可以看到:
-
請求Request :
- 請求的方式 GET
- 請求的地址 URL(http://task.browser.#/online/setpoint)
- 版本號(HTTP/1.1)
- 請求的頭部信息肛循,headers(Accept铭腕,Host,cookie等在于此處存著)
- 附屬體信息 (通常為自定義傳的參數(shù)多糠,這里并沒有體現(xiàn))
-
響應(yīng)Response :
- 版本號
- 狀態(tài)碼 (http協(xié)議的狀態(tài)碼)
- 相應(yīng)頭部信息headers (時間累舷、數(shù)據(jù)格式、編碼等信息)
- 附屬體信息(通常為相應(yīng)的自定義數(shù)據(jù)體)
那么問題來了夹孔,既然HTTP協(xié)議是有其規(guī)則的被盈,那么我們在設(shè)計API的時候,也應(yīng)該有一定的規(guī)則搭伤。這里頭最有名的就是RESTful API規(guī)范了只怎。
RESTful為何物?
首先來解釋下它的直面意思怜俐,它是Representational State Transfer的縮寫身堡,翻譯過來就是“表現(xiàn)層狀態(tài)轉(zhuǎn)換”。(直面意思都這么高深的樣子)其實這里省略了它的主語resource(資源)佑菩,即resource representational state transfer(資源表現(xiàn)層狀態(tài)轉(zhuǎn)換)盾沫。那資源指的又是什么呢?表現(xiàn)層又是什么殿漠?狀態(tài)轉(zhuǎn)化是做了什么呢赴精?
resource(資源):其實就是網(wǎng)絡(luò)上的某個信息,例如一段文本绞幌、一張圖片蕾哟、一首歌曲等。每個資源對應(yīng)一個特定的URL。要獲取這個資源谭确,訪問它的URL就可以帘营,因此URI就成了每一個資源的地址或獨一無二的識別符。
representation(表現(xiàn)層):"資源"是一種信息實體逐哈,它可以有多種外在表現(xiàn)形式芬迄。比如,一段文本我們可以用md格式或者txt等格式表現(xiàn)昂秃;圖片可以用JPG格式表現(xiàn)禀梳,也可以用PNG格式表現(xiàn)。我們把"資源"具體呈現(xiàn)出來的形式肠骆,叫做它的"表現(xiàn)層"算途。因此所說的表現(xiàn)層是建立在資源上的。
- state transfer(狀態(tài)轉(zhuǎn)換):我們知道蚀腿,客戶端與服務(wù)端是一種互動的關(guān)系嘴瓤,這就意味著,客戶端的操作會改變服務(wù)端資源的狀態(tài)莉钙,這種狀態(tài)的變換叫做state transfer(狀態(tài)轉(zhuǎn)換)廓脆,而這種狀態(tài)轉(zhuǎn)換是基于表現(xiàn)層,也就是說是對資源表現(xiàn)層的狀態(tài)轉(zhuǎn)換胆胰。所以就是"表現(xiàn)層狀態(tài)轉(zhuǎn)化"狞贱。
我們知道客戶端操作是通過HTTP請求對服務(wù)端資源操作的刻获,HTTP/1.1中蜀涨,請求方法有(GET, POST, PUT, PATCH, DELETE)這些,并且有具體的含義蝎毡。
GET(SELECT):從服務(wù)器取出資源(一項或多項)厚柳。
POST(CREATE):在服務(wù)器新建一個資源。
PUT(UPDATE):在服務(wù)器更新資源(客戶端提供改變后的完整資源)沐兵。
PATCH(UPDATE):在服務(wù)器更新資源(客戶端提供改變的屬性)别垮。
DELETE(DELETE):從服務(wù)器刪除資源。
介紹上面基本概念后扎谎,總結(jié)下RESTful到底是什么碳想,它就是:利用HTTP的請求方法去操作URL定位的資源,它是一種客戶端與服務(wù)端交互的一種規(guī)范毁靶。它的核心思想就是:URL只負責描述需要操作的資源胧奔,所以URL里頭不應(yīng)該有動詞,應(yīng)該是名詞预吆。HTTP負責描述操作龙填。
RESTful示例
例如一個關(guān)于組織機構(gòu)的API設(shè)計應(yīng)該這樣:
http://www.organization.com/orgs
http://www.organization.com/departments
http://www.organization.com/staffs
基于請求的方式和路徑來作為常見的CURD(增刪改查)
GET /orgs 列出所有組織
POST /orgs 新增一個或多個組織
GET /orgs/ID 查詢某個組織
PUT /orgs/ID 更新某個組織
DELETE /orgs/ID 刪除某個組織
GET /orgs/ID/departments 查詢某個組織下的所有部門
DELETE /orgs/ID/departments/ID/staffs 查詢某個組織下的某個部門的所有員工
對于請求后的響應(yīng)結(jié)果,RESTful也做了一個很好得定義:
GET /orgs:返回資源對象的列表(數(shù)組)
GET /orgs/resource:返回單個資源對象
POST /orgs:返回新生成的資源對象
PUT /orgs/resource:返回完整的資源對象
DELETE /orgs/resource:返回一個空文檔
RESTful設(shè)計誤區(qū)
最常見的一種設(shè)計錯誤,就是URI包含動詞岩遗。因為"資源"表示一種實體扇商,所以應(yīng)該是名詞,URL不應(yīng)該有動詞宿礁,動詞應(yīng)該放在HTTP協(xié)議中案铺。
RESTful優(yōu)點
- URL具有很強可讀性的,具有自描述性
- 可提供OpenAPI梆靖,便于第三方系統(tǒng)集成红且,提高互操作性;
RESTful的缺點
- 請求路徑將表內(nèi)關(guān)系完全暴露涤姊,響應(yīng)結(jié)果將表結(jié)構(gòu)暴露暇番,