RESTful API設計指南

2021-07-26 03:40:45 字數 3815 閱讀 1389

restful是representational state transfer的縮寫,代表著表徵狀態轉移。rest擁有一組架構約束條件和原則,只要符合這一套約束原則的架構,就是restful架構。

需要注意的是,rest並沒有提供新的元件、技術,也並不是專門為http提供規範,而是通過約束和原則去合理使用web的現有特徵和能力(是的,rest受到web現有特徵的影響還是比較深的)。restful api 是一種圍繞資源(resource)展開的無狀態傳輸的api設計方案。所有的http action,都應該是在相應resource上可以被操作和處理的,而api 就是對資源的管理操作,而這個具體操作是由 http action 指定的。

restful api在功能上更像是隔離層,要訪問伺服器資源,就必須找到api入口。如果這個入口的規則遵循rest風格,那就是restful設計框架。

資源的是乙個資料單元,這個單元可大可小,根據業務規模自主定製。要準確識別乙個資源,需要有乙個唯一標識,在web中這個唯一標識就是uri(uniform resource identifier)。

uri的設計應該具有自釋性,可定址性,直觀性的原則。用/來表示層級,用_或-來分割單詞,用?來過濾資源。

比較常見的uri:

除了post不是冪等的,其他幾個都是冪等的。

http的冪等性是指一次和多次請求某乙個資源應該具有同樣的***。冪等性的乙個例項:在網速不夠快的條件下,客戶端傳送第乙個請求後不能立即得到響應,由於不能確定是否請求是否被成功提交,所以它有可能會再次傳送另乙個相同的請求,冪等性決定了第二個請求是否有效。冪等情況下,第一次請求成功實現了事務操作,第二次請求就一定不能再次操作事務。

客戶端與服務端進行互動式,需要規定雙方能夠接受的**表現形式。常見的**格式型別有:

在設計restful api的時候,要規定端端之間具有統一的資料傳輸格式,目前json資料格式使用範圍比較廣。

大家都知道,api表達的是資料和資料使用者之間契約的說明。打破這樣一種契約會造成客戶端資料沒辦法正確獲取,文件的效果也大打折扣。

那乙個好的api是要應該做到可擴充套件的。隨著業務和服務的開張,這樣的api要成長為乙個公共平台的契約說明。為了做到廣義適配,需要有一定的規範,從而讓廣大的使用者輕鬆地消費這個平台的資料。api也容易使用,第三方呼叫者在使用上更為方便,使用者呼叫這個api來消費平台資料,這個平台的資料也更為有價值。

版本化資訊可以放在uri中,也可以放在請求頭裡面(github選擇前一種方案)

無論你正在構建什麼,無論你在入手前做了多少計畫,你核心的應用總會發生變化,資料關係也會變化,資源上的屬性也會被增加或刪除。只要你的專案還活著,並且有大量的使用者在用,這種情況總是會發生。

請謹記一點,api是伺服器與客戶端之間的乙個公共契約。如果你對伺服器上的api做了乙個更改,並且這些更改無法向後相容,那麼你就打破了這個契約,客戶端又會要求你重新支援它。為了避免這樣的事情,你既要確保應用程式逐步的演變,又要讓客戶端滿意。那麼你必須在引入新版本api的同時保持舊版本api仍然可用。

注:如果你只是簡單的增加乙個新的特性到api上,如資源上的乙個新屬性或者增加乙個新的端點,你不需要增加api的版本。因為這些並不會造成向後相容性的問題,你只需要修改文件即可。

隨著時間的推移,你可能宣告不再支援某些舊版本的api。申明不支援乙個特性並不意味著關閉或者破壞它。而是告訴客戶端舊版本的api將在某個特定的時間被刪除,並且建議他們使用新版本的api。

乙個好的restful api會在url中包含版本資訊。另一種比較常見的方案是在請求頭裡面保持版本資訊。但是跟很多不同的第三方開發者一起工作後,我可以很明確的告訴你,在請求頭裡面包含版本資訊遠沒有放在url裡面來的容易。

以為例,其根url是

這裡可能大家會有疑惑,前面提到的是uri,後面怎麼說的是url,其實這裡有一些包含與被包含的關係,用一張圖來說明。

大資料報的傳輸過程中容易丟包,針對這種情況,可以讓客戶端自己對結果做一些具體的過濾或限制,這麼做最重要的乙個原因是可以最小化網路傳輸,並讓客戶端盡可能快的得到查詢結果。其次是客戶端可能比較懶,如果這時伺服器能對結果做一些過濾或分頁,對大家都是好事。另外乙個不那麼重要的原因是(從客戶端角度來說),對伺服器來說響應請求的負載越少越好。

所以只要出現get的請求,就應該通過url來過濾資訊。以下有一些過濾器可以這麼新增到api中的:

http狀態碼是restful api很重要的一部分。它是乙個http標準,很多的網路裝置都可以識別這些狀態碼,例如負載均衡器可能會在發現某台web伺服器已經傳送了很多的50x伺服器錯誤之後,避免可能會通過配置避免傳送請求到這台伺服器上。

1xx範圍的狀態碼是保留給底層http功能使用的,並且估計在你的職業生涯裡面也用不著手動傳送這樣乙個狀態碼出來。

2xx範圍的狀態碼是保留給成功訊息使用的,你盡可能的確保伺服器總傳送這些狀態碼給使用者。

3xx範圍的狀態碼是保留給重定向用的。大多數的api不會太常使用這類狀態碼,但是在新的超**樣式的api中會使用更多一些。例如304是指資源未被改動,可以使用客戶端快取。

4xx範圍的狀態碼是保留給客戶端錯誤用的。例如,客戶端提供了一些錯誤的資料或請求了不存在的內容。這些請求應該是冪等的,不會改變任何伺服器的狀態。屬於客戶端錯誤

5xx範圍的狀態碼是保留給伺服器端錯誤用的。這些錯誤常常是從底層的函式丟擲來的,並且開發人員也通常沒法處理。傳送這類狀態碼的目的是確保客戶端能得到一些響應。收到5xx響應後,客戶端沒辦法知道伺服器端的狀態,所以這類狀態碼是要盡可能的避免。屬於服務端錯誤

oauth2.0提供了乙個請求的認證方式。在每乙個請求裡,可以明確知道哪個客戶端建立了請求,哪個使用者提交了請求,並且提供了一種標準的訪問過期機制或允許使用者從客戶端登出,所有這些都不需要第三方的客戶端知道使用者的登陸認證資訊。

還有oauth1.0和xauth同樣適用這樣的場景。無論你選擇哪個方法,請確保它為多種不同語言/平台上的庫提供了一些通用的並且設計良好文件,因為使用者可能會使用這些語言和平台來編寫客戶端。

api沒有文件,對於第三方開發者來說簡直是非常打擊的一件事。文件應該遵循以下規則:

具有良好的版式。

請求和響應的內容應該有完整的東西,並在文件中使用高亮語法。

文件的每乙個端點所預期的響應**和可能的錯誤訊息和錯誤訊息的出現場景說明。

可能的話,建立控制台來讓開發者立即體驗api的功能。(非必要)

保證文件的輸出格式能被列印。

github的api是restful api的一種實踐,可以當作參考來學習。

這裡摘取了github的幾個uri:

url中應該盡量使用專屬名詞,避免使用動詞。並將api部署在專用網域名稱之下。

路徑又稱為端點(endpoint),表示具體的位址。

在restful架構中,每個**都代表一種資源,所以**中不能有動詞,只能有名詞,所用的名詞往往和資料庫中的**名對應。

比如github的pulls和settings的路徑如下:

當需要設計乙個api時,可以去找特定領域內的特定設計,這樣就不必要重複設計輪子了。

在資料返回格式方面,大部分的**優先提供xml、json的資料返回,google定義的gdata就是在atom基礎上作了擴充套件,還有一些**提供了php的資料返回。

友好性主要表現在易擴充套件,後期需要的功能可以方便新增;

api也應該對上層ui友好,能夠靈活支援,並可以適用於任何作業系統。

RESTful API 設計指南

網路應用程式,分為前端和後端兩個部分。當前的發展趨勢,就是前端裝置層出不窮 手機 平板 桌面電腦 其他專用裝置 因此,必須有一種統一的機制,方便不同的前端裝置與後端進行通訊。這導致api構架的流行,甚至出現 api first 的設計思想。restful api是目前比較成熟的一套網際網路應用程式的...

RESTful API 設計指南

網路應用程式,分為前端和後端兩個部分。當前的發展趨勢,就是前端裝置層出不窮 手機 平板 桌面電腦 其他專用裝置.因此,必須有一種統一的機制,方便不同的前端裝置與後端進行通訊。這導致api構架的流行,甚至出現 api first 的設計思想。restful api是目前比較成熟的一套網際網路應用程式的...

RESTful API 設計指南

原文 網路應用程式,分為前端和後端兩個部分。當前的發展趨勢,就是前端裝置層出不窮 手機 平板 桌面電腦 其他專用裝置.因此,必須有一種統一的機制,方便不同的前端裝置與後端進行通訊。這導致 api 構架的流行,甚至出現 api first 的設計思想。restful api 是目前比較成熟的一套網際網...