RESTful架構API風格與相關規範

RESTful架構

一、概述:

  1. RESTful架構,就是目前最流行的一種互聯網軟件架構。REST是Representational State Transfer詞組的簡寫,即“表現層狀態轉化”。代表(互聯網資源)表現層狀態轉化。

  2. REST是Roy Fielding博士在2000年在其論文中第一個提到的,因爲他是互聯網行業內一個重要的人物(HTTP 1.0/1.1協議的主要設計者、Apache開源基金會的第一任主席),所以引起了人們的關注,並且對互聯網產生了深遠的影響。

  3. RESTful不是一個標準,但是一種規範。現在很多軟件使用使用前後端分離的應用結構,它結構清晰、符合標準、易於理解、擴展方便。前端(H5、Android、iPhone、小程序)往往通過調用API的方式與後端進行數據交換。那麼,符合RESTful規範的軟件架構的API我們可稱之爲RESTful APl。如微博開放API和Github開放API就嚴格遵循了RESTful規範。

以上是對RESTful架構的概述,在本文中,我將使用自己的理解完整的表述RESTful的規範,以及如何設計符合RESTful規範的API。實際上,在對計算機技術的理解中,一百個人可能會有一百種理解方式,儘管見仁見智,但我們的目的都是把技術當作工具,去實現我們的程序功能。如果在本文中的描述有所錯誤,或您有所不解,歡迎留言評論!

下面將分爲將分爲三個內容,展開描述我對RESTful的理解:

1.理解 RESTful
2.RESTful API架構規範
3.RESTful API 設計示例

二、理解RESTful

要理解RESTful,我們需要從每一個詞開始理解。Roy Fielding將他對互聯網軟件的架構原則命名爲REST,即Representational State Transfer的縮寫,代表(資源)表現層狀態轉化。如果一個軟件架構符合REST原則,就稱它爲RESTful架構。

1. 資源(Resources)

我們在互聯網軟件開發中,我們所說的“資源”是指在互聯網中某一個節點的具體信息,如一段文本、一張圖片、一個視頻、一個壓縮包、一個程序安裝包等等。在互聯網中,我們可以使用URI(統一資源定位符)來表示每一個具體的資源,因此,每一個互聯網資源都一個獨一無二的URI地址。

2. 表現層(Representational)

“資源”是一種信息的實體,實際上,資源有很多表現形成,如一段文本,我們可以使用普通的txt格式來表示,也可以用JSON格式來表示,還可以使用XML格式來表示。“資源”的具體表現形式我們就叫做表現層。在HTTP協議中,規定了頭信息中的Content-Type字段來描述具體的資源表現形式。如“Content-Type: text/html”表示爲html格式的文本數據,而“Content-Type: text/json”表示爲JSON格式的文本數據。

1. 狀態轉化(State Transfer)

HTTP是一種無狀態的網絡協議,如果客戶端要操作服務器,必須通過一種手段通知服務器進行“狀態轉化”,而這種狀態改變建立在“表現層”之上,這就是“表現層狀態轉化”。在HTTP協議中,客戶端通過發送相應的請求告知服務器實現某種狀態的改變。客戶端使用GET、POST、PUT、DELETE4個表示操作方式的動詞對服務端資源進行操作。

綜上所述,我們可以總結一下RESTful的特點:
a. 每個互聯網資源都有一個唯一的URI地址;
b. 通過操作資源的表現形式來操作資源;
c. 一般情況下使用JSON格式來表示具體的數據;
c. 使用HTTP協議進行客戶端與服務端之間的交互,從客戶端到服務端的每個請求都必須包含理解請求所必需的信息;
d. 客戶端使用GET、POST、PUT、DELETE 4個表示操作方式的動詞對服務端資源進行“狀態”操作。

三、RESTful API架構規範

REST並沒有明確的設計標準,可以說RESTful是一種設計風格的規範化。在RESTful API設計中,不同的組織可能還存在不同的設計風格規範,但是整體上RESTful的風格規範是一致的。

也正是因爲有了一致的風格規範,讓讀API的人更好地理解API,甚至不用閱讀文檔,就知道API要實現的某個資源的某種“狀態轉化”。根據Github開放API或者微博開放API的設計風格。下面是我總結的RESTful API的相關風格規範,今後我將使用此規範進行API開發。

1. 協議

客戶端與服務器之間使用HTTP或者HTTPS協議進行通信。

2.域名

應當儘量將API程序部署到專有的域名之下,如:

https://api.demo.com

如果API比較簡單,或者不考慮進行擴展,應當放在項目的子模塊中,如:

https://demo.com/api/

3.API版本

應當將API版本放在URL中,如微博開放API就將版本號放在URL中:

http://api.weibo.com/2/

如果我們把版本號理解成資源的不同表述形式的話,API版本應放在HTTP請求頭Accept字段中,如github中的開放API

Accept: application/vnd.github.v3

可能github考慮很多因素,所以把請求的API版本放到HTTP請求頭裏了。實際上,如果我們想要快速的開發一個API程序,使用第一種形式會更加直觀與方便。

4.路徑

對於不同的資源,都有一個唯一的URL地址,每一個URL地址代表一種資源,所以網址中應當是名稱,不能是動詞,而且名詞應當與數據庫表名對應。一般來說,數據庫中保存的是數據集合,所以URL中對應的資源應當是名詞複數。

如Github開放API中,列出一個組織的項目集合:

https://api.github.com/orgs/:org/projects

在上面URL中,orgs代表組織集合,而:org代表集體的組織名,projects代表具體的資源

5.HTTP動詞

對於資源的某種具體操作類型,需要客戶端發送不同的HTTP動作來完成。
常用的五個HTTP動詞已經對應操作如下:

* GET(Retrieve):從服務器取出資源(一項或多項);
* POST(CREATE):在服務器新建一個資源;
* PUT(UPDATE):在服務器更新資源(客戶端提供改變後的完整資源);
* PATCH(UPDATE):在服務器更新資源(客戶端提供改變的屬性);
* DELETE(DELETE):從服務器刪除資源。

實際上,最常用的額HTTP動詞原先只有4個,即GET、POST、PUT、DELETE,PATCH方法是新引入的,是對PUT方法的補充,用來對已知資源進行局部更新。

有時候,只需要修改一個屬性,開發者通常(爲圖省事)把一個包含了修改後完整信息傳給後端,做完整更新。但實際上如果需要考慮性能優化,是有必要做局部更新的。

6.過濾

在獲取服務器資源的時候,大部分情況是需要進行過濾的,而不是獲取數據庫中的完整集合。這時候需要設置過濾條件,我們可以將過濾條件作爲參數拼接到URL中。如下:

?limit=10  # 指定獲取10條信息集合
?page=1&limit=10  # 指定每頁10條信息,獲取第1頁信息集合
?limit=10&deleted=true  # 獲取數據庫中已經標誌爲刪除的10條信息集合

7.返回

使用相應的HTTP狀態碼,將結果告知客戶端,以下是常用的HTTP狀態碼以及狀態描述:

狀態碼 描述 備註
200 OK - 成功
204 NO CONTENT - 無內容 DELETE返回204狀態碼,表示資源已經不存在
303 See Other - 其他 表示參考另一個 URL,此時應當返回URL鏈接
400 bad request - 服務器不理解客戶端的請求(如,參數錯誤)
401 Unauthorized - 沒有通過身份驗證
403 Forbidden - 沒有訪問權限
404 Not Found - 資源不存在,或不可用
405 Method Not Allowed - 對於此HTTP方法沒有權限
409 conflict - 通用衝突 如被請求的資源與其當前狀態之間存在衝突,請求無法完成
410 Gone - 資源不存在,或不可用
415 unsupported media type - 不支持的媒體類型 如服務器需要客戶端使用JSON數據請求,而客戶端使用XML進行請求
429 Too Many Requests - 請求次數超過限額
500 internal server error - 服務器通用錯誤 如果客戶端請求有效,服務器處理時發生了意外
503 Service Unavailable - 服務端當前無法處理請求 如網站正在維護,服務器無法處理請求
  • 正常:如果正常返回數據,應當使用msg或者其他關鍵字作爲鍵名返回給客戶端,如下:
{
"data":[
    "user_id":1,
    "name":"張三",
    "token":"csdcnsdvndsijudsao",
],
"message":"OK",
"code":200
}
  • 錯誤:如果發生錯誤,應當使用error作爲錯誤信息的鍵名返回給客戶端
{
"error":"Unauthorized",
"code":401
}

針對不同操作,服務器向用戶返回的結果應該符合以下規範:

GET /collection:返回資源對象的列表(數組)
GET /collection/resource:返回單個資源對象
POST /collection:返回新生成的資源對象
PUT /collection/resource:返回完整的資源對象
PATCH /collection/resource:返回完整的資源對象
DELETE /collection/resource:返回一個空文檔

8.Hypermedia API

RESTful API最好做到Hypermedia,即超媒體,在返回結果中提供鏈接,連向其他API方法或者一些文檔,使得用戶不查文檔,也知道下一步應該做什麼。如Github就做到了Hypermedia,使用GET方式請求 https://api.github.com ,會返回一系列的鏈接地點:

{
  "current_user_url": "https://api.github.com/user",
  "current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}",
  "authorizations_url": "https://api.github.com/authorizations",
  "code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}",
  "commit_search_url": "https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}",
.....

四、RESTful API設計示例

RESTful API風格主要體現在URL中,接下來,我們通過一個示例,來完成RESful API的URL制定。假設我們要開發一個簡單的博客系統,要給H5、Android、iPhone、小程序提供一套統一的接口。那麼預設功能與對應URL已經請求方式如下:

模塊 功能 URL HTTP請求方式
用戶 用戶註冊 http://api.demo.com/1.0/users/register POST
用戶 用戶登錄 http://api.demo.com/1.0/users/login POST
文章 發表文章 http://api.demo.com/1.0/articles POST
文章 查看文章 http://api.demo.com/1.0/articles/:id GET
文章 修改文章 http://api.demo.com/1.0/articles/:id PUT
文章 刪除文章 http://api.demo.com/1.0/aritcles/:id DELETE

到此結束。

本文爲作者原創文章,禁止轉載,原作者:https://phy.xyz

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