1. 程式人生 > >RESTful API淺談

RESTful API淺談

隨筆 - 192  文章 - 0  評論 - 204

上半年時候,部門有組織的討論了一下實踐微服務的技術話題,主要內容是SOA服務和微服務各自的優勢和難點,其中有提到關於RESTful API設計方法。

正好最近在深入的學習HTTP協議,也看了一些有關RESTful API的資料,這篇部落格,就將自己的一些理解整理記錄一下。

PS:本篇部落格主要談一些概要的設計思想和方法,不談具體的實現細節,如有誤差歡迎指出,謝謝!

想進一步瞭解RESTful API,建議學習下面列出的一些詞條:

HTTP協議、分散式系統架構原理(CAP)、作業系統原理。。。

參考資料:

一、REST的由來

全稱:REST,全稱是Resource Representational State Transfer,即:資源在網路中以某種形式進行狀態轉移。————所謂狀態的轉移,可參考《HTTP權威指南》一書中對協議的詳細解釋,此處不過多贅述!

定義:簡單來說REST是一種系統架構設計風格(而非標準),一種分散式系統的應用層解決方案。

背景:早期的網頁端是前後臺一起的,比如PHP、JSP等。而隨著近幾年移動端的快速發展和分散式架構的應用,各種Client層出不窮,這個時候就需要有個統一的機制,來為前後端通訊提供服務。

     而RESTful API就是目前比較成熟的的一套應用程式API設計理論。

目的:Client和Server端進一步解耦。

應用:最為經典的莫過於github API。

二、RESTful的特徵和優點

1、客戶端-伺服器(Client-Server):提供服務的伺服器和使用服務的客戶端分離解耦;

   優點:提高客戶端的便捷性(操作簡單)

        簡化伺服器提高可伸縮性(高效能、低成本)

        允許客戶端服務端分組優化,彼此不受影響

2、無狀態(Stateless):來自客戶的每一個請求必須包含伺服器處理該請求所需的所有資訊(請求資訊唯一性);

   優點:提高可見性(可以單獨考慮每個請求)

        提高可靠性(更容易故障恢復)

        提高了可擴充套件性(降低了伺服器資源使用)

3、可快取(Cachable):伺服器必須讓客戶端知道請求是否可以被快取?如果可以,客戶端可以重用之前的請求資訊傳送請求;

   優點:減少互動連線數

        減少連線過程的網路時延

4、分層系統(Layered System):允許伺服器和客戶端之間的中間層(代理,閘道器等)代替伺服器對客戶端的請求進行迴應,而客戶端不需要關心與它互動的元件之外的事情;

   優點:提高了系統的可擴充套件性

        簡化了系統的複雜性

5、統一介面(Uniform Interface):客戶和伺服器之間通訊的方法必須是統一化的。(例如:GET,POST,PUT.DELETE)

   優點:提高互動的可見性

        鼓勵單獨優化改善元件

6、支援按需程式碼(Code-On-Demand,可選):伺服器可以提供一些程式碼或者指令碼並在客戶的執行環境中執行。

   優點:提高可擴充套件性

三、概要設計方法

1、協議

API與Client的通訊協議,總是使用HTTPS協議。

PS:使用HTTPS協議和RESTful API本身沒有多大關係,但是對於增加網站的安全是非常重要的,特別是如果提供的是公開的API,那麼HTTPS久更顯得重要了。

2、域名

應該儘量將API部署在專用的域名下面,比如:

 https://api.github.com 

如果API變化較大,可以把API設計為子域名,比如:

 https://example.com/api/v1 

3、版本(Versioning)

一般而言應該將API放入URL中,比如:

 https://example.com/api/v1 

還可以將版本號放入HTTP資訊頭中,但這樣不如放入URL方便和直觀。

4、路徑(Endpoint)

在協議中,每個網址代表一種資源的存放地址,所以網址終不能有動詞,只能有名詞,而且名詞一般都應該與資料庫的表字段對應,且API中的名詞應該使用複數。例如:

/users/:username/repos
/users/:org/repos
/repos/:owner/:repo
/repos/:owner/:repo/tags
/repos/:owner/:repo/branches/:branch

PS:根據RFC3986定義,URL是大小寫敏感的,所以應該儘量使用小寫字母來命名!

5、方法(Method)

有了資源的URL設計,所有針對資源的操作都是使用HTTP方法指定的,常見的方法有(括號中為對應的SQL命令):

Verd 描述
HEAD(SELECT) 只獲取某個資源的頭部資訊
GET(SELECT) 獲取資源
POST(CREATE) 建立資源
PATCH(UPDATE) 更新資源的部分屬性(很少用,一般用POST代替)
PUT(UPDATE) 更新資源,客戶端需要提供新建資源的所有屬性
DELETE(DELETE) 刪除資源

比如:

GET /user:列出所有的使用者POST /user:新建一個使用者PATCH /user/ID:更新某個指定使用者的資訊DELETE /user/ID:刪除所有使用者

6、資料過濾(Filtering)

如果資料量太大,伺服器不可能將所有資料返回給使用者。API應該提供引數(比如Query),過濾返回結果。比如:

?limit=10:指定返回記錄的數量
?offset=10:指定返回記錄的開始位置
?page=2&per_page=100:指定第幾頁,以及每頁的記錄數
?sortby=name&order=asc:指定返回結果按照哪個屬性排序,以及排序順序
?state=close:指定篩選條件

7、狀態碼

在HTTP報文構成中,有個欄位很重要:status code。它說明請求的大致情況,是否正常處理、出現了什麼錯誤等。狀態碼都是三位數,大概分為了一下幾個區間:

狀態碼 描述
2XX 請求正常處理並返回
3XX 重定向,請求的資源位置發生變化
4XX 客戶端傳送的請求有誤
5XX 伺服器端的錯誤

關於狀態碼,具體的介紹可以去我之前的部落格HTTP狀態碼或者參考其他資料,這裡不過多贅述。

8、錯誤處理

如果出錯的話,在response body中應通過message欄位,以鍵值對的格式,給出明確的錯誤資訊。

最基本的思路應該是:儘可能提供準確的錯誤資訊,比如資料格式不正確、缺少某個欄位......而不是直接說“請求錯誤”之類的資訊。

9、Hypermedia API

Restful API的設計最好做到Hypermedia:即在返回結果中提供相關資源的連結,連向其他API方法,使使用者不需要查文件也知道下一步做什麼。

這樣做的好處是,使用者可以根據返回結果就能得到後續操作需要訪問的地址。

10、身份驗證

一般來說,讓任何人隨意訪問公開的 API 是不好的做法,驗證和授權是兩件事情:

驗證(Authentication):確定使用者是其申明的身份,比如提供賬戶的密碼。不然的話,任何人偽造成其他身份(比如其他使用者或者管理員)是非常危險的;

授權(Authorization):保證使用者有對請求資源特定操作的許可權。比如使用者的私人資訊只能自己能訪問,其他人無法看到;有些特殊的操作只能管理員可以操作,其他使用者有隻讀的許可權等。

如果沒有通過驗證,需要返回401 Unauthorized狀態碼,並在 body 中說明具體的錯誤資訊;而沒有被授權訪問的資源操作,需要返回403 Forbidden狀態碼,還有詳細的錯誤資訊。

PS:Github API 對某些使用者未被授權訪問的資源操作返回404 Not Found,目的是為了防止私有資源的洩露(比如黑客可以自動化試探使用者的私有資源,返回 403 的話,就等於告訴黑客使用者有這些私有的資源)。

11、編寫文件

API最終是給人使用的,無論是對內還是對外,即使遵循上面提到的所有規則,API設計的很優雅,但有時候使用者還是不知道該如何使用這些提供的API。

因此,編寫清晰可讀的文件是很必要的事情。

而且編寫文件也可以作為產出物的一部分,以及用來做記錄,以方便查詢參考。

以上內容為我個人整理記錄的關於RESTful API的概要內容,感興趣的童鞋可以自行查閱其他資料,本部落格不保證內容的完全正確性!

Has anything you've done made your life better?