RESTful API定義及使用規範

首發於fxm5547的博客html

RESTful自己是一種風格而不是規範,本文爲該風格的規範實現的最佳實踐,本文檔詳細說明了HTTP RESTful API的定義和使用規範,做爲接口調用者和實現者的重要參考。android

接口風格

遵循RESTful設計風格,同時控制複雜度及易於使用,僅遵循大部分原則。 遵循原則:ios

  • 使用https協議
  • 版本號放入URL或Header
  • 只提供json返回格式
  • post,put上使用json做爲輸入
  • 使用http狀態碼做爲錯誤提示
  • Path(路徑)儘可能使用名詞,不使用動詞,把每一個URL當作一個資源
  • 使用HTTP動詞(GET,POST,PUT,DELETE)做爲action操做URL資源
  • 過濾信息
    • limit:指定返回記錄數量
    • offset:記錄開始位置
    • direction:請求數據的方向,取值prev-上一頁數據;next-下一頁數據
    • page:第幾頁
    • per_page:每頁條數
    • total_count:總記錄數
    • total_pages:總頁數,等於page時,表示當前是最後一頁
    • sort:column1,column2排序字段
    • orderby:排序規則,desc或asc
    • q:搜索關鍵字(uri encode以後的)
  • 返回結果
    • GET:返回資源對象
    • POST:返回新生成的資源對象
    • PUT:返回完整的資源對象
    • DELETE:返回一個空文檔
  • 速率限制
    • X-RateLimit-Limit: 每一個IP每一個時間窗口最大請求數
    • X-RateLimit-Remaining: 當前時間窗口剩餘請求數
    • X-RateLimit-Reset: 下次更新時間窗口的時間(UNIX時間戳),達到下個時間窗口時,Remaining恢復爲Limit

未遵循原則:git

  • Hypermedia API(HATEOAS),經過接口URL獲取接口地址及幫助文檔地址信息
  • 限制返回值的域,fields=id,subject,customer_name
  • 緩存,使用ETag和Last-Modified

參考:github

模塊和版本說明

接口模塊相互對立且有版本管理,模塊名做爲APP配置項進行存儲,每一個模塊的版本號version和endpoint在應用初始化時調用api模塊信息接口(經過傳遞客戶端應用名稱和版本號獲取各個API模塊的endpoint和version)獲取並存儲web

  • 示例模塊及最新版本號:
模塊 模塊用途 最新版本號
account 賬戶 v1
sms 短信 v1
open 一些開放接口,不須要公共參數 v1

公共參數

Headers

公共請求參數是指每一個接口均可能須要傳遞的參數,公共參數經過header傳遞。chrome

參數 是否必須 說明及header格式
app 全部接口必須 請求客戶端應用標識,取值*-ios、*-android、*-pc、*-h5
header格式:
X-Co-App: $app
user_id App登陸後全部接口都傳
Web經過session機制獲取
用戶標識
header格式:
Authorization: CoAPI base64(user_id:token)
token App登陸後全部接口都傳
Web經過session機制獲取
受權訪問令牌
header格式:
Authorization: CoAPI base64(user_id:token)
  • Web應用經過cookies傳遞session id,user_id和token無需傳遞,接口會從session自動獲取;json

  • 同一token值在App和Web各應用間通用(token即爲session id);api

  • **APP修改user-agent,在原有user-agent的尾部添加$app/$versionNetType/$value。**如:瀏覽器

    • Dalvik/2.1.0 (Linux; U; Android 6.0.1; MI 4LTE MIUI/V7.5.3.0.MXGCNDE) $app-android/3.0.0 NetType/4G
    • Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) $app-ios/3.0.0 NetType/WIFI
  • app取值及釋義示例

app取值 客戶端名稱【域名】
admin-pc 管理中心PC網頁版【admin.url.com】
admin-h5 管理中心手機網頁版【admin.url.com】
admin-ios 管理中心iOS版
admin-android 管理中心Android版

Cookies

  • **用於告知服務端是否支持Webp的Cookie:**cookie name是supportWebp,取值是1(支持)和0(不支持),未傳遞時服務端默認取值爲0。
  • Webview植入Session的Cookie:

JWT & OAuth2

  • Json Web Token可用於替代session-cookie機制。但會存在一些問題,好比爲過時token強制失效問題(用戶修改了密碼後,沒法強制其餘的終端token所有失效)。
  • OAuth2是受權其餘開發者訪問本身應用有限權限的受權機制。

權限

  • 權限分爲
    • none:無需任何受權;
    • token:須要用戶登陸受權,可經過header AuthorizationCookie CoSID傳遞;
    • admintoken:須要管理員登陸受權,可經過header AuthorizationCookie CoCPSID傳遞;
    • token || admintoken:用戶登陸受權或管理員登陸受權均可以;
      圖片
    • sign:須要簽名,通常用於服務端內部相互調用,詳見[ API HMAC-SHA1簽名]({% post_url 2017-11-08-API-HMAC-SHA1-Sign %})。

狀態碼說明

正確
接口正常訪問狀況下,服務器返回2××的HTTP狀態碼。

HTTP狀態碼
200 OK - 表示已在響應中發出、資源更改爲功(GET、PUT)
201 Created - 新資源被建立(POST)
204 No Content - 資源被刪除(DELETE)

錯誤
當用戶訪問接口出錯時,服務器會返回給一個合適的4××或者5××的HTTP狀態碼;以及一個application/json格式的消息體,消息體中包含錯誤碼code和錯誤說明message。

  • 5××錯誤(500=<status code)爲服務器或程序出錯,客戶端只須要提示「服務異常,請稍後重試」便可,該類錯誤不在每一個接口中列出。
  • 4××錯誤(400=<status code<500)爲客戶端的請求錯誤,須要根據具體的code作相應的提示和邏輯處理,message僅供開發時參考,不建議做爲用戶提示。
  • 部分錯誤示例:
code message HTTP狀態碼
InvalidToken 未登陸或受權過時,請登陸 401 Unauthorized
ValidationError 輸入字段驗證出錯,缺乏字段或字段格式有誤 422 Unprocessable Entity
AccountNotExist 帳戶名不存在 404 Not Found
InvalidPassword 密碼錯誤 401 Unauthorized
NotFound 請求的資源不存在 404 Not Found
AccountHasExist 帳戶名已經存在 409 Conflict
MobileHasBinded 手機號已經綁定其餘帳戶 409 Conflict
InvalidSign 參數簽名驗證未經過 403 Forbidden
InvalidSMSCode 短信驗證碼錯誤 403 Forbidden
ExpiredSMSCode 過時的短信驗證碼 403 Forbidden
FrequencyLimit 發送過於頻繁,請稍後再試 403 Forbidden
TimesExceeded 達到最大發送次數限制,請明天再試 403 Forbidden
VerifyTimesExceeded 達到最大校驗次數,請明天再試 403 Forbidden
RateLimitExceeded 接口調用次數超過限制,請稍後再試 429 Too Many Requests
|    |
複製代碼

InternalError |服務異常,請稍後再試 |500 Internal Server Error

參數傳遞

遵循RESTful規範,使用了GET, POST, PUT, DELETE共4種請求方法。

  1. GET:請求資源,返回資源對象
  2. POST:新建資源,返回新生成的資源對象
  3. PUT:新建/更新資源,返回完整的資源對象
  4. DELETE:刪除資源,返回body爲空
  • GET請求不容許有body, 全部參數經過拼接在URL以後傳遞,全部的請求參數都要進行遵循RFC 3986的URL Encode
  • DELETE刪除單個資源時,資源標識經過path傳遞,批量刪除時,經過在body中傳遞JSON。
  • POST, PUT請求,全部參數經過JSON傳遞,可選的請求參數,只傳有值的,無值的不要傳遞,contentType爲application/json。

4種請求動做中,GET、PUT、DELETE是冪等的;只有POST是非冪等的。冪等操做的特色是其任意屢次執行所產生的影響均與一次執行的影響相同。 是非冪等是判斷接口使用POST仍是PUT的決定條件

注意: APP端獲取json數據時,對於數值類型字段必須以數值類型轉換,不管傳遞過來的值是否帶引號。

圖片
圖片

速率限制Rate Limiting

  • 爲了防止API被惡意調用,對API調用進行速率限制。
  • 速率限制爲每IP每15分鐘5000次(dev/qa爲10W)調用(15分鐘是一個時間窗口)。
  • 限制是針對全部接口模塊一塊兒計算的(Redis key爲APIRL:{IP}),暫時沒有特殊的模塊或單個接口(將來可能有)。
  • 你能夠經過每一個接口返回的HTTP headers瞭解當前速率限制的狀況:
    • X-RateLimit-Limit: 每一個IP每一個時間窗口最大請求數
    • X-RateLimit-Remaining: 當前時間窗口剩餘請求數
    • X-RateLimit-Reset: 下次更新時間窗口的時間(UNIX時間戳),達到下個時間窗口時,Remaining恢復爲Limit
  • 超出速率限制,返回如下錯誤
    圖片

安全注意事項

  • 用戶登陸後用戶的token;aliyun OSS的bucket、AccessKey ID與AccessKey secret;微視頻的appid、sign、bucket;這些關鍵數據經過調用接口得到,須要在客戶端以安全的方式存儲。
  • 音頻視頻在APP內的存儲,不容許被拷貝(即便越獄或root後拿走也沒法使用)。

測試工具

推薦Chrome瀏覽器插件Postman做爲接口測試工具, Postman下載地址

圖片

文檔生成工具

  • 生成的工具爲apidoc,詳細閱讀官方文檔:http://apidocjs.com

調用示例

  • 僞代碼

    圖片

  • PHP

    圖片

API模塊信息獲取

  • App配置文件中僅存儲api模塊名,App初始化時請求獲取api模塊信息,獲取各個api模塊的信息(endpoint和version)。

接口文檔參考示例

接口文檔參考示例

相關文章
相關標籤/搜索