RESTful API淺談

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

正好最近在深刻的學習HTTP協議,也看了一些有關RESTful API的資料,這篇博客,就將本身的一些理解整理記錄一下。git

PS:本篇博客主要談一些概要的設計思想和方法,不談具體的實現細節,若有偏差歡迎指出,謝謝!github

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

HTTP協議、分佈式系統架構原理(CAP)、操做系統原理。。。數據庫

參考資料:後端

跟着Github學習TESTful HTTP API設計api

一種RESTful API接口的約定緩存

RESTful API設計最佳實踐安全

知乎:如何用通俗易懂的語言解釋RESTful API?服務器

 

1、REST的由來

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

出現:REST最先是由Roy Fielding博士發表的論文中提到的,他也曾參與設計了HTTP協議。論文地址:http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

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

背景:早期的網頁端是先後臺一塊兒的,好比PHP、JSP等。而隨着近幾年移動端的快速發展和分佈式架構的應用,各類Client層出不窮,這個時候就須要有個統一的機制,來爲先後端通訊提供服務。

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

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

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

 

2、RESTful的特徵和優勢

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

   優勢:提升客戶端的便捷性(操做簡單)

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

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

二、無狀態(Stateless):來自客戶的每個請求必須包含服務器處理該請求所需的全部信息(請求信息惟一性);

   優勢:提升可見性(能夠單獨考慮每一個請求)

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

        提升了可擴展性(下降了服務器資源使用)

三、可緩存(Cachable):服務器必須讓客戶端知道請求是否能夠被緩存?若是能夠,客戶端能夠重用以前的請求信息發送請求;

   優勢:減小交互鏈接數

        減小鏈接過程的網絡時延

四、分層系統(Layered System):容許服務器和客戶端之間的中間層(代理,網關等)代替服務器對客戶端的請求進行迴應,而客戶端不須要關心與它交互的組件以外的事情;

   優勢:提升了系統的可擴展性

        簡化了系統的複雜性

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

   優勢:提升交互的可見性

        鼓勵單獨優化改善組件

六、支持按需代碼(Code-On-Demand,可選):服務器能夠提供一些代碼或者腳本並在客戶的運行環境中執行。

   優勢:提升可擴展性

 

3、概要設計方法

一、協議

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

PS:使用HTTPS協議和RESTful API自己沒有多大關係,可是對於增長網站的安全是很是重要的,特別是若是提供的是公開的API,那麼HTTPS久更顯得重要了。

二、域名

應該儘可能將API部署在專用的域名下面,好比:

 https://api.github.com 

若是API變化較大,能夠把API設計爲子域名,好比:

 https://example.com/api/v1 

三、版本(Versioning)

通常而言應該將API放入URL中,好比:

 https://example.com/api/v1 

還能夠將版本號放入HTTP信息頭中,但這樣不如放入URL方便和直觀。

四、路徑(Endpoint)

在協議中,每一個網址表明一種資源的存放地址,因此網址終不能有動詞,只能有名詞,並且名詞通常都應該與數據庫的表字段對應,且API中的名詞應該使用複數。例如:

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

PS:根據RFC3986定義,URL是大小寫敏感的,因此應該儘可能使用小寫字母來命名!

五、方法(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:刪除全部用戶

六、數據過濾(Filtering)

若是數據量太大,服務器不可能將全部數據返回給用戶。API應該提供參數(好比Query),過濾返回結果。好比:

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

七、狀態碼

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

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

關於狀態碼,具體的介紹能夠去我以前的博客HTTP狀態碼或者參考其餘資料,這裏不過多贅述。

八、錯誤處理

若是出錯的話,在response body中應經過message字段,以鍵值對的格式,給出明確的錯誤信息。

最基本的思路應該是:儘量提供準確的錯誤信息,好比數據格式不正確、缺乏某個字段......而不是直接說「請求錯誤」之類的信息。

九、Hypermedia API

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

這樣作的好處是,用戶能夠根據返回結果就能獲得後續操做須要訪問的地址。

十、身份驗證

通常來講,讓任何人隨意訪問公開的 API 是很差的作法,驗證和受權是兩件事情:

驗證(Authentication):肯定用戶是其申明的身份,好比提供帳戶的密碼。否則的話,任何人僞形成其餘身份(好比其餘用戶或者管理員)是很是危險的;

受權(Authorization):保證用戶有對請求資源特定操做的權限。好比用戶的私人信息只能本身能訪問,其餘人沒法看到;有些特殊的操做只能管理員能夠操做,其餘用戶有隻讀的權限等。

若是沒有經過驗證,須要返回401 Unauthorized狀態碼,並在 body 中說明具體的錯誤信息;而沒有被受權訪問的資源操做,須要返回403 Forbidden狀態碼,還有詳細的錯誤信息。

PS:Github API 對某些用戶未被受權訪問的資源操做返回404 Not Found,目的是爲了防止私有資源的泄露(好比黑客能夠自動化試探用戶的私有資源,返回 403 的話,就等於告訴黑客用戶有這些私有的資源)。

十一、編寫文檔

API最終是給人使用的,不管是對內仍是對外,即便遵循上面提到的全部規則,API設計的很優雅,但有時候用戶仍是不知道該如何使用這些提供的API。

所以,編寫清晰可讀的文檔是很必要的事情。

並且編寫文檔也能夠做爲產出物的一部分,以及用來作記錄,以方便查詢參考。

 

以上內容爲我我的整理記錄的關於RESTful API的概要內容,感興趣的童鞋能夠自行查閱其餘資料,本博客不保證內容的徹底正確性!

相關文章
相關標籤/搜索