Restful HTTP API 設計分解
摘要
什麼是 RESTful RESTful 是一種軟體設計風格,或者直接理解為API介面編寫的規範。 RESTful特點
- 安全可靠,高效,易擴充套件
- 簡單明瞭,可讀性強,沒有歧義
- API風格統一,呼叫規則,傳入引數和返回資料有統一的標準
RESTful設計原則
1、HTTPS
HTTPS 為介面的安全提供了保障,可以有效防止通訊被竊聽和篡改。而且現在部署 HTTPS 的成本也越來越低,你可以通過 cerbot 等工具,方便快速的製作免費的安全證書,所以生產環境,請務必使用 HTTPS。
注意:非 HTTPS 的 API 呼叫,不要重定向到 HTTPS,而要直接返回呼叫錯誤以禁止不安全的呼叫。
https://api.larabbs.com
或者可以放到主域名下,例如:
https://www.larabbs.com/api
3、版本控制 隨著業務的發展,需求的不斷變化,API 的迭代是必然的,很可能當前版本正在使用,而我們就得開發甚至上線一個不相容的新版本,為了讓舊使用者可以正常使用,為了保證開發的順利進行,我們需要控制好 API 的版本。
通常情況下,有兩種做法:
將版本號直接加入 URL 中
https://api.larabbs.com/v1 https://api.larabbs.com/v2
使用HTTP請求頭的Accept欄位進行區分
https://api.larabbs.com/
Accept: application/prs.larabbs.v1+json
Accept: application/prs.larabbs.v2+json
4、用URL定位資源 在 RESTful 的架構中,所有的一切都表示資源,每一個 URL 都代表著一種資源,資源應當是一個名詞,而且大部分情況下是名詞的複數,儘量不要在 URL 中出現動詞。 先來看看 github 的 例子:
GET /issues 列出所有的 issue GET /orgs/:org/issues 列出某個專案的 issue GET /repos/:owner/:repo/issues/:number 獲取某個專案的某個 issue POST /repos/:owner/:repo/issues 為某個專案建立 issue PATCH /repos/:owner/:repo/issues/:number 修改某個 issue PUT /repos/:owner/:repo/issues/:number/lock 鎖住某個 issue DELETE /repos/:owner/:repo/issues/:number/lock 接收某個 issue
例子中冒號開始的代表變數,例如 /repos/summerblue/larabbs/issues
在 github 的實現中,我們可以總結出:
資源的設計可以巢狀,表明資源與資源之間的關係。 大部分情況下我們訪問的是某個資源集合,想得到單個資源可以通過資源的 id 或number 等唯一標識獲取。 某些情況下,資源會是單數形式,例如某個專案某個 issue 的鎖,每個 issue 只會有一把鎖,所以它是單數。
錯誤的例子:
POST https://api.larabbs.com/createTopic
GET https://api.larabbs.com/topic/show/1
POST https://api.larabbs.com/topics/1/comments/create
POST https://api.larabbs.com/topics/1/comments/100/delete
正確的例子:
POST https://api.larabbs.com/topics
GET https://api.larabbs.com/topics/1
POST https://api.larabbs.com/topics/1/comments
DELETE https://api.larabbs.com/topics/1/comments/100
5、用HTTP動詞描述操作 HTTP 設計了很多動詞,來表示不同的操作,RESTful 很好的利用的這一點,我們需要正確的使用 HTTP 動詞,來表明我們要如何操作資源。 6、資源過濾 我們需要提供合理的引數供客戶端過濾資源,例如:
?state=closed: 不同狀態的資源
?page=2&per_page=100:訪問第幾頁資料,每頁多少條。
?sortby=name&order=asc:指定返回結果按照哪個屬性排序,以及排序順序。
7、正確的使用狀態碼 HTTP提供了豐富的狀態碼,正確的使用狀態碼可以讓相應資料具有可讀性。 在狀態碼的設計編排上儘量遵守HTTP的狀態碼,由於各公司的實際業務不同,狀態碼的選擇上通常從10000開始編排。 8、資料相應格式 考慮到響應資料的可讀性及通用性,預設使用 JSON 作為資料響應格式。如果客戶端有需求使用其他的響應格式,例如 XML,需要在 Accept 頭中指定需要的格式。
https://api.larabbs.com/
Accept: application/prs.larabbs.v1+json
Accept: application/prs.larabbs.v1+xml
對於錯誤資料,預設使用如下結構:
'message' => ':message', // 錯誤的具體描述
'errors' => ':errors', // 引數的具體錯誤描述,422 等狀態提供
'code' => ':code', // 自定義的異常碼
'status_code' => ':status_code', // http狀態碼
'debug' => ':debug', // debug 資訊,非生產環境提供
例如:
{
"message": "422 Unprocessable Entity",
"errors": {
"name": [
"姓名 必須為字串。"
]
},
"status_code": 422
}
{
"message": "您無權訪問該訂單",
"status_code": 403
}
9、呼叫的頻率限制 為了防止伺服器被攻擊,減少伺服器壓力,需要對介面進行合適的限流控制,需要在響應頭資訊中加入合適的資訊,告知客戶端當前的限流情況
- X-RateLimit-Limit :100 最大訪問次數
- X-RateLimit-Remaining :93 剩餘的訪問次數
- X-RateLimit-Reset :1513784506 到該時間點,訪問次數會重置為 X-RateLimit-Limit
超過限流次數後,需要返回 429 Too Many Requests 錯誤。 10、編寫文件 為了方便使用者使用,我們需要提供清晰的文件,儘可能包括以下幾點
- 包括每個介面的請求引數,每個引數的型別限制,是否必填,可選的值等。
- 響應結果的例子說明,包括響應結果中,每個引數的釋義。
- 對於某一類介面,需要有儘量詳細的文字說明,比如針對一些特定場景,介面應該如何呼叫。
總結: 以上概念需結合實際專案,目的是養成一個規範的介面編碼習慣。