RESTful API定義及使用規(guī)范

首發(fā)于fxm5547的博客

RESTful本身是一種風格而不是規(guī)范,本文為該風格的規(guī)范實現(xiàn)的最佳實踐,本文檔詳細說明了HTTP RESTful API的定義和使用規(guī)范,作為接口調(diào)用者和實現(xiàn)者的重要參考。

接口風格

遵循RESTful設(shè)計風格,同時控制復雜度及易于使用,僅遵循大部分原則。
遵循原則:

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

未遵循原則:

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

參考:

模塊和版本說明

接口模塊相互對立且有版本管理,模塊名作為APP配置項進行存儲,每個模塊的版本號version和endpoint在應(yīng)用初始化時調(diào)用api模塊信息接口(通過傳遞客戶端應(yīng)用名稱和版本號獲取各個API模塊的endpoint和version)獲取并存儲。

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

公共參數(shù)

Headers

公共請求參數(shù)是指每個接口都可能需要傳遞的參數(shù),公共參數(shù)通過header傳遞。

參數(shù) 是否必須 說明及header格式
app 所有接口必須 請求客戶端應(yīng)用標識,取值*-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機制獲取
授權(quán)訪問令牌
header格式:
Authorization: CoAPI base64(user_id:token)
  • Web應(yīng)用通過cookies傳遞session id,user_id和token無需傳遞,接口會從session自動獲??;

  • 同一token值在App和Web各應(yīng)用間通用(token即為session id);

  • 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網(wǎng)頁版【admin.url.com】
admin-h5 管理中心手機網(wǎng)頁版【admin.url.com】
admin-ios 管理中心iOS版
admin-android 管理中心Android版

Cookies

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

JWT & OAuth2

  • Json Web Token可用于替代session-cookie機制。但會存在一些問題,比如為過期token強制失效問題(用戶修改了密碼后,無法強制其他的終端token全部失效)。
  • OAuth2是授權(quán)其他開發(fā)者訪問自己應(yīng)用有限權(quán)限的授權(quán)機制。

權(quán)限

  • 權(quán)限分為
    • none:無需任何授權(quán);
    • token:需要用戶登錄授權(quán),可通過header AuthorizationCookie CoSID傳遞;
    • admintoken:需要管理員登錄授權(quán),可通過header AuthorizationCookie CoCPSID傳遞;
    • token || admintoken:用戶登錄授權(quán)或管理員登錄授權(quán)都可以;
      圖片
    • sign:需要簽名,一般用于服務(wù)端內(nèi)部相互調(diào)用,詳見[ API HMAC-SHA1簽名]({% post_url 2017-11-08-API-HMAC-SHA1-Sign %})。

狀態(tài)碼說明

正確
接口正常訪問情況下,服務(wù)器返回2××的HTTP狀態(tài)碼。

HTTP狀態(tài)碼
200 OK - 表示已在響應(yīng)中發(fā)出、資源更改成功(GET、PUT)
201 Created - 新資源被創(chuàng)建(POST)
204 No Content - 資源被刪除(DELETE)

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

  • 5××錯誤(500=<status code)為服務(wù)器或程序出錯,客戶端只需要提示“服務(wù)異常,請稍后重試”即可,該類錯誤不在每個接口中列出。
  • 4××錯誤(400=<status code<500)為客戶端的請求錯誤,需要根據(jù)具體的code做相應(yīng)的提示和邏輯處理,message僅供開發(fā)時參考,不建議作為用戶提示。
  • 部分錯誤示例:
code message HTTP狀態(tài)碼
InvalidToken 未登錄或授權(quán)過期,請登錄 401 Unauthorized
ValidationError 輸入字段驗證出錯,缺少字段或字段格式有誤 422 Unprocessable Entity
AccountNotExist 賬戶名不存在 404 Not Found
InvalidPassword 密碼錯誤 401 Unauthorized
NotFound 請求的資源不存在 404 Not Found
AccountHasExist 賬戶名已經(jīng)存在 409 Conflict
MobileHasBinded 手機號已經(jīng)綁定其他賬戶 409 Conflict
InvalidSign 參數(shù)簽名驗證未通過 403 Forbidden
InvalidSMSCode 短信驗證碼錯誤 403 Forbidden
ExpiredSMSCode 過期的短信驗證碼 403 Forbidden
FrequencyLimit 發(fā)送過于頻繁,請稍后再試 403 Forbidden
TimesExceeded 達到最大發(fā)送次數(shù)限制,請明天再試 403 Forbidden
VerifyTimesExceeded 達到最大校驗次數(shù),請明天再試 403 Forbidden
RateLimitExceeded 接口調(diào)用次數(shù)超過限制,請稍后再試 429 Too Many Requests
InternalError 服務(wù)異常,請稍后再試 500 Internal Server Error

參數(shù)傳遞

遵循RESTful規(guī)范,使用了GET, POST, PUT, DELETE共4種請求方法。

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

4種請求動作中,GET、PUT、DELETE是冪等的;只有POST是非冪等的。冪等操作的特點是其任意多次執(zhí)行所產(chǎn)生的影響均與一次執(zhí)行的影響相同。 是非冪等是判斷接口使用POST還是PUT的決定條件

注意: APP端獲取json數(shù)據(jù)時,對于數(shù)值類型字段必須以數(shù)值類型轉(zhuǎn)換,無論傳遞過來的值是否帶引號。

圖片

圖片

速率限制Rate Limiting

  • 為了防止API被惡意調(diào)用,對API調(diào)用進行速率限制。
  • 速率限制為每IP每15分鐘5000次(dev/qa為10W)調(diào)用(15分鐘是一個時間窗口)。
  • 限制是針對所有接口模塊一起計算的(Redis key為APIRL:{IP}),暫時沒有特殊的模塊或單個接口(未來可能有)。
  • 你可以通過每個接口返回的HTTP headers了解當前速率限制的情況:
    • X-RateLimit-Limit: 每個IP每個時間窗口最大請求數(shù)
    • X-RateLimit-Remaining: 當前時間窗口剩余請求數(shù)
    • X-RateLimit-Reset: 下次更新時間窗口的時間(UNIX時間戳),達到下個時間窗口時,Remaining恢復為Limit
  • 超出速率限制,返回以下錯誤


    圖片

安全注意事項

  • 用戶登錄后用戶的token;aliyun OSS的bucket、AccessKey ID與AccessKey secret;微視頻的appid、sign、bucket;這些關(guān)鍵數(shù)據(jù)通過調(diào)用接口獲得,需要在客戶端以安全的方式存儲。
  • 音頻視頻在APP內(nèi)的存儲,不允許被拷貝(即使越獄或root后拿走也無法使用)。

測試工具

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

圖片

文檔生成工具

調(diào)用示例

  • 偽代碼


    圖片
  • PHP


    圖片

API模塊信息獲取

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

接口文檔參考示例

接口文檔參考示例

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容