REST 一詞,是由 HTTP 協議的主要設計者 Roy Fielding 在他 2000 年的博士論文中提出的。git
論文地址:https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htmgithub
在這篇論文中,Roy Fielding 闡述了一種 Web 軟件的架構風格(Architectural Style),並將其命名爲 REST,即 Representational State Transfer(表徵性狀態轉移) 的縮寫。web
論文中描述了 REST 的六大軟件工程原則,符合這些原則的架構被稱爲 RESTful 架構。數據庫
C/S架構。api
無狀態:服務端不記錄客戶端的狀態,客戶端的每次請求中都必須包含充分的信息,以便於服務端可以識別客戶端的狀態。緩存
統一的接口服務器
可緩存:客戶端容許緩存服務端響應的內容。網絡
系統分層:在終端服務器與客戶端之間容許存在中間層(如代理服務器)。架構
按需編碼(可選):服務端能夠經過給客戶端返回一段功能代碼(如 Javascript 代碼)讓客戶端來執行,從而實現某些特定的功能。編輯器
做爲 HTTP 協議的主要設計者,Roy Fielding 提出的 REST 架構風格偏偏是對 HTTP 協議的提倡與使用指導。HTTP 協議自己是一種面向資源的應用層協議,可是開發者們對 HTTP 的使用方式並不統一,不少 Web 服務的開發者們都並無徹底把 HTTP 看成應用層協議,而只是把它當作傳輸層協議來用,而後在 HTTP 之上又創建起了本身的應用層協議。這是 Roy Fielding 不但願看到的。
他倡導開發者們充分利用 HTTP 協議的特性(例如使用 HTTP Method 來指定對目標資源的操做)、聽從 HTTP 設計思想來開發 Web 服務。
從某種意義上來講,REST 架構風格就是聽從了 HTTP 設計思想的 Web 架構風格。
RESTful 是 「REST」 的形容詞形式,即「符合 REST 架構風格的」。符合 REST 架構風格的架構稱爲 RESTful 架構;符合 REST 架構風格的 Web 服務稱爲 RESTful Web 服務;符合 REST 架構風格的 Web API 稱爲 RESTful API。
Python 爬蟲庫 BeautifulSoup 的做者 Leonard Richardson 提出了一個成熟度模型,該模型把 RESTful Web 服務按照成熟度劃分紅 4 個層次:
URI 中儘可能使用名詞,原則上不使用動詞,即 URI 僅用做對資源的標識。
經過 HTTP Method 來指定對資源的操做。如 GET 表示獲取資源、POST 表示新建資源、PUT 表示全局更新資源(須要在請求體中包含完整的目標資源的表現層,於是不推薦使用),PATCH 表示局部更新資源,DELETE 表示刪除資源。
URI 中的名詞通常採用複數形式,表示某類資源的集合,如 /tickets
表示所有 ticket 的集合。
若是要表示集合中的單個資源,就在後面拼接這個資源的ID。如 /tickets/12
,表示 ID 爲12的那個 ticket。
使用QueryString篩選集合中的元素,如 /tickets?status=1&sum>=100
,表示狀態爲1且金額>=100的 ticket 的集合。
經過 URI 的層層遞進來創建資源的父子關係,如 /tickets/12/collections/3
,表示 ID 爲12的那個 ticket 下的 ID 爲3的 collection。
使用形容詞來定製對某類資源的查詢結果,如 /tickets/recently_closed
表示最近關閉的 ticket 的集合,/tickets/a_specialized
表示專門給a定製的 ticket 的集合。
爲了支持複雜查詢,建議提供 /queries
,當客戶端須要傳遞的參數過多時,容許客戶端 POST /queries
,將查詢參數放在請求體中傳遞過去, /queries
服務負責將請求體映射成一個 query 實體並寫入數據庫,而後返回 query_id。客戶端拿到 query_id 後再 GET /tickets?query_id=111
。
關於分頁,HTTP 推薦將分頁信息放在 Link
響應頭中,參考 GitHub API 的設計,以下:
Link: <https://api.github.com/user/repos?page=3&per_page=100>; rel="next",<https://api.github.com/user/repos?page=2&per_page=100>; rel="pre",<https://api.github.com/user/repos?page=1&per_page=100>; rel="first",<https://api.github.com/user/repos?page=50&per_page=100>; rel="last",
101 Switching Protocols:表示須要切換網絡協議,此時客戶端應當斷開 HTTP 鏈接,使用指定的協議從新與服務端創建鏈接。
200 OK:表示一切正常。
201 Created :表示資源已成功建立,新資源的 URL 位於 Location
響應頭中,用戶能夠選擇在須要的時候訪問它。
301 Moved Permanently:表示目標資源被永久轉移,新的 URL 位於 Location
響應頭中,此時客戶端應當對新的 URL 發起請求。
302 Found:表示目標資源被臨時轉移,新的 URL 位於 Location
響應頭中,此時客戶端應當對新的 URL 發起請求。
303 See Other:表示請求已被處理,但未返回處理結果,此時客戶端應當請求另外一個資源來獲取處理結果,該資源的 URL 位於 Location
響應頭中。
307 Temporary Redirect:表示請求還沒有被處理,是由於請求的資源不在本地,而在另外一個 URL 處,客戶端應當對那個 URL 發起請求,該 URL 位於 Location
響應頭中。
307 與 303 的區別:對於 GET 請求來講,307 與 303 沒有區別,對於 POST、PUT、DELETE 請求來講,它們的區別在於,307 說明請求的操做還沒有執行,而 303 說明請求的操做已經執行過了。
400 Bad Request:表示用戶發起的請求有問題,服務端沒法處理該請求。
401 Unauthorized:表示用戶對該資源的訪問還沒有獲得受權。
403 Forbidden:表示用戶無權訪問該資源。
404 Not Found:表示目標資源不存在。
415 Unsupported Media Type:表示請求體的媒體類型與服務端所指望的不符。
429 Too Many Requests:表示用戶請求的次數過多,超出了服務端的限速閾值。
500 Internal Server Error:表示服務端內部出現異常。
502 Bad Gateway:表示客戶端代理方面出現異常。
503 Service Unavailable:表示服務端因繁忙或故障而拒絕本次服務,並經過響應頭Retry-After告知客戶端什麼時候能夠重試。