RESTful API定義及使用規范

首發于fxm5547的博客

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

接口風格

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

  • 使用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

未遵循原則:

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

參考:

模塊和版本說明

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

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

公共參數

Headers

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

參數 是否必須 說明及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自動獲??;

  • 同一token值在App和Web各應用間通用(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網頁版【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下載地址

圖片

文檔生成工具

調用示例

  • 偽代碼


    圖片
  • PHP


    圖片

API模塊信息獲取

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

接口文檔參考示例

接口文檔參考示例

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,283評論 6 530
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 97,947評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,094評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,485評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,268評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,817評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,906評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,039評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,551評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,502評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,662評論 1 366
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,188評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,907評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,304評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,563評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,255評論 3 389
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,637評論 2 370