RESTful架構與RESTful API設計
一、REST的由來
REST這個詞是Roy Thomas Fielding博士在他2000年的博士論文中提出的,Fielding將他對網際網路軟體的架構原則定名為REST,即Representational State Transfer的縮寫,翻譯為“表現層狀態轉化”。如果一個架構符合REST原則,就稱它為RESTful架構,即REST風格的架構。
二、REST是什麼
REST是一種架構風格,而不是一種架構。要理解RESTful架構,最好的方法就是去理解Representational State Transfer這個詞到底是什麼意思,他的每一個詞代表什麼含義。如果你把這個名詞搞懂了,就不難體會REST是一種什麼樣的設計。
資源(Resources)
REST的名稱“表現層狀態轉化”中省略了主語。“表現層”其實是指的“資源(Resources)”的“表現層”。
所謂“資源”,就是網路上的一個實體,或者是網路上的一個具體資訊。它可以是一段文字、一張圖片、一首歌曲、一種服務、總之就是一個具體的實體。你可以用一個URI(統一資源識別符號)指向它,每種資源對應一個特定的URL。要獲取這個資源,訪問它的URI就可以,因此URI就成了每一個資源的地址或獨一無二的識別符。
表現層(Representation)
“資源”是一種資訊實體,他可以有多種的外在表現形式。我們把“資源”具體呈現出來的形式稱之為“表現層”
URI只代表資源的實體,不代表他的形式。嚴格地說,有些網址最後的“.html”字尾名是不必要的,因為這個字尾名錶示格式,屬於“表現層”的範疇,而URI應該只代表“資源”的位置。它的具體表現形式應該在HTTP請求的頭資訊中用Accept和Content-Type欄位指定,這兩個欄位才是對“表現層”的描述,不過在大部分應用中,通過後綴區分表現層就已經足夠了。
狀態轉化(State Transfer)
訪問一個網站,就代表了客戶端和伺服器的一個互動過程。在這個過程中,勢必涉及資料和狀態的變化。
HTTP協議是一個無狀態網際網路通訊協議,這意味著所有狀態都儲存在伺服器端。因此,如果客戶端想要操作伺服器,必須通過某種手段,讓伺服器發生“狀態轉化(State Transfer)”。而這種轉化是建立在表現層之上的,所以就叫做“表現層狀態轉化”。
客戶端用到的手段只能是HTTP協議。具體的說,HTTP協議裡有5個常用的表示操作方式的動詞:GET、POST、PUT、DELETE、PATCH。它們分別對應5種基本操作:GET用來獲取資源,POST用來新建資源(也可以用來更新資源),PUT用來更新資源,DELETE用來刪除資源,PATCH用來更新資源的部分屬性。
三、RESTful架構
現在流行的各種Web框架,包括Spring Boot都支援REST開發,REST並非是一種技術或者規範,而是一種架構風格,這種架構風格逐漸各種程式語言的Web框架所支援。它包括了REST架構中如何標識資源,如何表示操作介面及操作版本,如何標識操作結果等,主要內容如下:
- 使用“api”作為Web上下文;
- 增加版本標識;
- 標識資源;
- REST中的HTTP Method;
- REST中的HTTP Status;
1)使用“api”作為上下文:
也有的使用“api”作為二級域名:
2)增加一個版本標識
也有的做法是將版本資訊放到HTTP頭,但這裡推薦還是通過URl來實現,這樣使得REST的相關程式碼更加容易閱讀。
3)標識資源
將資源名稱放到URL中,如果資源有層級關係,則放入層級關係:
如果使用者屬於系統管理,也可以這麼寫:
4)確定HTTP Method
在REST中,HTTP Method常常對應一下含義:
- POST:代表增加資源;
- PUT:代表更改資源,客戶端提供完整的資源屬性;
- GET:代表查詢資源;
- PATCH:更新資源,客戶端提供僅需要更改的資源屬性;
- DELETE:通常用於刪除資源;
- HEAD:類似GET,但僅僅只有HTTP頭資訊,頭資訊中包含了需要查詢的資訊;
- OPTIONS,用於獲取URI所支援的方法,相應資訊會在HTTP頭中包含一個名為“Allow”的頭,值是所支援的方法,如“GET、POST”;
在業務系統中,刪除往往並不是指的物理刪除,而是邏輯刪除,資源通常仍在資料庫中,只是狀態設定為刪除狀態。
RESTful API設計的一些例子
新增使用者:
查詢id為45的使用者
查詢所有使用者:
如果有翻頁,可以在後面增加類似offset、limit引數,比如:
GET:http://192.168.0.1/api/v1.1/system/user?offset=1&limit=20&sortBy=name
更新使用者id為45的使用者:
刪除使用者id為45的使用者:
注意:可以為資源標識新增字尾,使得REST程式碼更加容易閱讀,比如:
返回id為45的使用者資訊,返回格式是json
5)確定HTTP Status
伺服器向客戶端返回HTTP Status以表示操作是否成功,常用的如下:
- 200,OK,使用者請求成功,如查詢資料成功返回。
- 400,錯誤的請求。
- 404 ,NOT Found,使用者發出的請求針對的資源不存在,通常是Spring Boot中的Controller沒有匹配上URI,或者匹配上了Controller方法,但是渲染的檢視不存在。
- 405,用來訪問本頁面的HTTP Method不被允許。
- 406,表示無法使用請求的內容特性來相應請求資源,比如在Spring Boot中,請求字尾以html結尾,但同時請求的HTTP頭中又包含Accept:application/json。
- 500,伺服器內部錯誤,無法完成請求,通常是Controller丟擲的異常。
四、RESTful總結
1)每一個URI代表一種資源。
2)客戶端和伺服器之間傳遞這種資源的表現層。
3)客戶端通過HTTP動詞,對伺服器端資源進行操作,實現“表現層狀態轉化”。
一句話概括:URI定位資源,用HTTP動詞(GET,POST,DELETE,DETC)描述操作。
五、REST VS. WebService
REST和WebService主要的差別就是前者是一種輕量級的架構,而後者是一種重量級架構。前者即適合終端到服務的呼叫,系統內部子系統的互相呼叫,也適合不同公司之間的系統互相呼叫,而WebService較為適合不同公司之間系統的呼叫。
注:有不明白WebService的同學請看下面的參考資料。
六、參考資料
理解RESTful架構
RESTful API 設計指南
有關WebService的文章:
Web service是什麼?
Web Service技術的SOAP實現
Web Services 系列教程
Web API知識
到底 REST 和 SOAP、RPC 有何區別?