1. 程式人生 > >Restful HTTP API 設計分解

Restful HTTP API 設計分解

摘要

什麼是 RESTful RESTful 是一種軟體設計風格,或者直接理解為API介面編寫的規範。 RESTful特點

  1. 安全可靠,高效,易擴充套件
  2. 簡單明瞭,可讀性強,沒有歧義
  3. API風格統一,呼叫規則,傳入引數和返回資料有統一的標準

RESTful設計原則

1、HTTPS HTTPS 為介面的安全提供了保障,可以有效防止通訊被竊聽和篡改。而且現在部署 HTTPS 的成本也越來越低,你可以通過 cerbot 等工具,方便快速的製作免費的安全證書,所以生產環境,請務必使用 HTTPS。 注意:非 HTTPS 的 API 呼叫,不要重定向到 HTTPS,而要直接返回呼叫錯誤以禁止不安全的呼叫。

2、域名 應當儘可能的將 API 與其主域名區分開,可以使用專用的域名,訪問我們的 API,例如(推薦使用):

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、編寫文件 為了方便使用者使用,我們需要提供清晰的文件,儘可能包括以下幾點

  • 包括每個介面的請求引數,每個引數的型別限制,是否必填,可選的值等。
  • 響應結果的例子說明,包括響應結果中,每個引數的釋義。
  • 對於某一類介面,需要有儘量詳細的文字說明,比如針對一些特定場景,介面應該如何呼叫。

總結: 以上概念需結合實際專案,目的是養成一個規範的介面編碼習慣。