Laravel 開發 API 注意事項
Restful:全稱為 Representational State Transfer,直譯為表現層狀態轉移,或許可以解釋為用 URL 定位資源,用 HTTP 動詞描述操作。
RESTful 設計原則
* HTTPS
HTTPS 為介面的安全提供了保障,可以有效防止通訊被竊聽和篡改。而且現在部署 HTTPS 的成本也越來越低,你可以通過 cerbot 等工具,方便快速的製作免費的安全證書,所以生產環境,請務必使用 HTTPS。另外注意,非 HTTPS 的 API 呼叫,不要重定向到 HTTPS,而要直接返回呼叫錯誤以禁止不安全的呼叫。
* 域名
應當儘可能的將 API 與其主域名區分開,可以使用專用的域名,訪問我們的 API,
例如:https://api.larabbs.com或者可以放在主域名下,例如:https://www.larabbs.com/api
* 版本控制
隨著業務的發展,需求的不斷變化,API 的迭代是必然的,很可能當前版本正在使用,而我們就得開發甚至上線一個不相容的新版本,為了讓舊使用者可以正常使用,為了保證開發的順利進行,我們需要控制好 API 的版本。
通常情況下,有兩種做法:
1)將版本號直接加入 URL 中
https://api.larabbs.com/v1
https://api.larabbs.com/v2
2)使用 HTTP 請求頭的 Accept 欄位進行區分
https://api.larabbs.com/
Accept: application/prs.larabbs.v1+json
Accept: application/prs.larabbs.v2+json
Github Api 雖然預設使用了第一種方法,但是其實是推薦並實現了第二種方法的,我們同樣也儘量使用第二種方式。
* 用 URL 定位資源
在 RESTful 的架構中,所有的一切都表示資源,每一個 URL 都代表著一種資源,資源應當是一個名詞,而且大部分情況下是名詞的複數,儘量不要在 URL 中出現動詞。
例:
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
· 資源的設計可以巢狀,表明資源與資源之間的關係。
· 大部分情況下我們訪問的是某個資源集合,想得到單個資源可以通過資源的 id 或number 等唯一標識獲取。
· 某些情況下,資源會是單數形式,例如某個專案某個 issue 的鎖,每個 issue 只會有一把鎖,所以它是單數。
* 用 HTTP 動詞描述操作
HTTP 設計了很多動詞,來表示不同的操作,RESTful 很好的利用的這一點,我們需要正確的使用 HTTP 動詞,來表明我們要如何操作資源。
先來解釋一個概念,冪等性,指一次和多次請求某一個資源應該具有同樣的副作用,也就是一次訪問與多次訪問,對這個資源帶來的變化是相同的。
常用的動詞及冪等性
路由動作
動詞 描述 是否冪等
GET 獲取資源,單個或多個 是
POST 建立資源 否
PUT 更新資源,客戶端提供完整的資源資料 是
PATCH 更新資源,客戶端提供部分的資源資料 否
DELETE 刪除資源 是
注)為什麼 PUT 是冪等的而 PATCH 是非冪等的,因為 PUT 是根據客戶端提供了完整的資源資料,客戶端提交什麼就替換為什麼,而 PATCH 有可能是根據客戶端提供的引數,動態的計算出某個值,例如每次請求後資源的某個引數減1,所以多次呼叫,資源會有不同的變化。
* 資源過濾
我們需要提供合理的引數供客戶端過濾資源,
例如
?state=closed: 不同狀態的資源
?page=2&per_page=100:訪問第幾頁資料,每頁多少條。
?sortby=name&order=asc:指定返回結果按照哪個屬性排序,以及排序順序。
* 正確使用狀態碼
HTTP 提供了豐富的狀態碼供我們使用,正確的使用狀態碼可以讓響應資料更具可讀性。
200 OK - 對成功的 GET、PUT、PATCH 或 DELETE 操作進行響應。也可以被用在不建立新資源的 POST 操作上
201 Created - 對建立新資源的 POST 操作進行響應。應該帶著指向新資源地址的 Location 頭
202 Accepted - 伺服器接受了請求,但是還未處理,響應中應該包含相應的指示資訊,告訴客戶端該去哪裡查詢關於本次請求的資訊
204 No Content - 對不會返回響應體的成功請求進行響應(比如 DELETE 請求)
304 Not Modified - HTTP快取header生效的時候用
400 Bad Request - 請求異常,比如請求中的body無法解析
401 Unauthorized - 沒有進行認證或者認證非法
403 Forbidden - 伺服器已經理解請求,但是拒絕執行它
404 Not Found - 請求一個不存在的資源
405 Method Not Allowed - 所請求的 HTTP 方法不允許當前認證使用者訪問
410 Gone - 表示當前請求的資源不再可用。當呼叫老版本 API 的時候很有用
415 Unsupported Media Type - 如果請求中的內容型別是錯誤的
422 Unprocessable Entity - 用來表示校驗錯誤
429 Too Many Requests - 由於請求頻次達到上限而被拒絕訪問
* 資料響應格式
考慮到響應資料的可讀性及通用性,預設使用 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
}
* 呼叫頻率限制
為了防止伺服器被攻擊,減少伺服器壓力,需要對介面進行合適的限流控制,需要在響應頭資訊中加入合適的資訊,告知客戶端當前的限流情況
X-RateLimit-Limit :100 最大訪問次數
X-RateLimit-Remaining :93 剩餘的訪問次數
X-RateLimit-Reset :1513784506 到該時間點,訪問次數會重置為 X-RateLimit-Limit
超過限流次數後,需要返回 429 Too Many Requests 錯誤。
* 編寫文件
為了方便使用者使用,我們需要提供清晰的文件,儘可能包括以下幾點
· 包括每個介面的請求引數,每個引數的型別限制,是否必填,可選的值等。
· 響應結果的例子說明,包括響應結果中,每個引數的釋義。
· 對於某一類介面,需要有儘量詳細的文字說明,比如針對一些特定場景,介面應該如何呼叫。
API
Auth::guard('api')->user(); // 登入使用者例項
Auth::guard('api')->check(); // 使用者是否登入
Auth::guard('api')->id(); // 登入使用者ID