Restful API 風(fēng)格

實(shí)際上就是用RESTful風(fēng)格來包裝HTTP協(xié)議,并用json或xml格式實(shí)現(xiàn)數(shù)據(jù)交互。

RESTful風(fēng)格: 網(wǎng)絡(luò)資源實(shí)體化,CURD對(duì)資源進(jìn)行操作。

好的規(guī)范評(píng)判標(biāo)準(zhǔn):直觀、擴(kuò)展、優(yōu)雅

1.數(shù)據(jù)交互格式

推薦json, 緊湊、易于讀寫、占用帶寬小、各種編程語言支持。以下均已json格式為例。

HTTP 請(qǐng)求頭:

## 客戶端接受數(shù)據(jù)類型,服務(wù)端根據(jù)Accept字段調(diào)整返回消息的數(shù)據(jù)格式
Accept:application/json; charset=UTF-8 # >>>推薦
# 或  :application/xml; charset=UTF-8  # xml
# 或  :application/json,application/xml; charset=UTF-8 # xml或者json

## 客戶端發(fā)送數(shù)據(jù)類型
Content-Type:application/json; charset=UTF-8  # >>>推薦
# 或        :application/x-www-form-urlencoded; charset=UTF-8  # 不推薦
# 或        :multipart/form-data; charset=UTF-8  # >>>推薦用于上傳文件
# 或        :application/xml; charset=UTF-8  # xml

HTTP 消息頭:

## 服務(wù)端端返回消息數(shù)據(jù)類型
Content-Type:application/json; charset=UTF-8  # >>>推薦
# 或        :application/xml; charset=UTF-8   # xml

2.授權(quán)認(rèn)證

由于HTTP是無狀態(tài)協(xié)議,所以客戶端需要攜帶一串經(jīng)過加密的不易重復(fù)的密碼串來追蹤用戶。web中的session機(jī)制,OAuth2.0中的tooken。
比如:md5 36^32=6.3+E49 100億用戶重復(fù)的概率是億億億億分之一

2.1 針對(duì)web客戶端設(shè)計(jì)

由于web應(yīng)用開發(fā)已經(jīng)有成熟的用戶追蹤解決方案,即Session-Cookie,API設(shè)計(jì)可以延用這一方案。當(dāng)客戶端請(qǐng)求Session不存在或過期的時(shí)候,接口返回響應(yīng)錯(cuò)誤碼要求用戶登陸;客戶端登陸成功后把session ID和其他用戶信息放在Cookie里,客戶端再次請(qǐng)求時(shí)攜帶該信息。

HTTP 消息頭:

Cookie:sessionId=39rkgbkm2qqt0k9d9qmnr68difn9bs9q;userId=1;userRole=admin;  # "sessionId"鍵名可以由服務(wù)端自定義

HTTP 請(qǐng)求頭:

Cookie:sessionId=39rkgbkm2qqt0k9d9qmnr68difn9bs9q;userId=1;userRole=admin;  # "sessionId"鍵名可以由服務(wù)端自定義
2.2 針對(duì)純API客戶端設(shè)計(jì)

客戶端不是瀏覽器時(shí)或客戶端不支持Cookie時(shí),另起一個(gè)頭字段“User”,當(dāng)然可以是其他字段甚至可以是“Cookie”,純粹習(xí)慣問題。客戶端獲取數(shù)居前需要解析下這個(gè)請(qǐng)求頭字段(瀏覽器會(huì)自動(dòng)解析Cookie字段)。

HTTP 消息頭:

User:token=39rkgbkm2qqt0k9d9qmnr68difn9bs9q;userId=1;userRole=admin;  # "token"鍵名可以由服務(wù)端自定義

HTTP 請(qǐng)求頭:

User:token=39rkgbkm2qqt0k9d9qmnr68difn9bs9q;userId=1;userRole=admin;  # "token"鍵名可以由服務(wù)端自定義
2.3 通用型

如果以上2.1和2.2兩種情況都用“Cookie”頭字段,省事了沒有這一步;2.2用“User”的話就需要做個(gè)判斷處理。

2.4 個(gè)人推薦
User:tooken=39rkgbkm2qqt0k9d9qmnr68difn9bs9q;userId=1;userRole=admin;

3.API命名

API指的是服務(wù)端的資源實(shí)體,它可以是一段文本、一張圖片、一首歌曲、一種服務(wù),總之就是一個(gè)具體的實(shí)在。所以API名稱一定是名稱,通常以復(fù)數(shù)居多,對(duì)應(yīng)數(shù)據(jù)庫中的一張表,比如“users、goods、orders”。“轉(zhuǎn)賬”就可以當(dāng)作一種服務(wù): GET http://.../transfer?from=a&to=b&amount=100

遞進(jìn)從屬關(guān)系表達(dá),如:http://.../orders/1/goods/1,表示訂單ID為1的訂單下面商品ID為1的商品。

3.請(qǐng)求

一次請(qǐng)求就是對(duì)服務(wù)的資源的一次操作,操作即增、刪、改、查,對(duì)應(yīng)HTTP四種請(qǐng)求方法:GET(查)、POST(增)、PUT(改)、DELETE(刪)。
另有PATCH(打補(bǔ)丁)方法,指局部跟新,PUT指全量更新;但一般PUT當(dāng)全量更新用,而PATCH方法不用。

還有OPTIONS方法,是對(duì)該接口參數(shù)和功能的說明,類似于命令行中的"--help",建議使用。

## 建議在消息頭說明
Allow:GET, POST, PUT, DELETE, OPTIONS
3.1 CURD舉例
GET    http://.../goods     # 列表     ?page=1&page_size=10&order_by=price&desc=1&filters={"price":{"min":10,"max":20}}
GET    http://.../goods/1   # 詳情
POST   http://.../goods     # 新增     -d '{"name":"番茄","price":"3.00"}'
POST   http://.../goods     # 批量新增 -d '[{"name":"番茄","price":"3.00"}, ...]'
PUT    http://.../goods/1   # 更新     -d '{"name":"番茄","price":"3.50"}'
PUT    http://.../goods     # 批量更新 -d '[{"id":1,name":"番茄","price":"3.00"}, ...]'
DELETE http://.../goods/1   # 刪除
DELETE http://.../goods/1,2 # 批量刪除
3.2 輔助參數(shù)

某種特殊情況下,需要對(duì)接口行為作出調(diào)節(jié),需要客戶端額外的傳參;為了防止沖突,這種參數(shù)通常以"_"開頭。比如深度鏈接喚起應(yīng)用、分享鏈接

# 模擬請(qǐng)求方法
_method=GET/POST/PUT/DELETE

# 標(biāo)記碼
_token=39rkgbkm2qqt0k9d9qmnr68difn9bs9q

# 防止跨域攻擊標(biāo)記碼
_CSRF_token=39rkgbkm2qqt0k9d9qmnr68difn9bs9q

# 格式化輸出
_format=json

4.消息體

標(biāo)準(zhǔn)的消息體由三個(gè)部分組成:

{
    "code":200,       // 狀態(tài)碼,參考http狀態(tài)碼,建議二者保持一致, 見[6.錯(cuò)誤碼]
    "msg":"SUCCESS",  // 簡(jiǎn)短消息,可供客戶端直接打印輸出
    "data":{},        // 數(shù)據(jù)包
}

4.1 列表

GET http://.../goods

{
    "code":200,
    "msg":"SUCCESS",
    "data":{
        "list":[{...}, {...}],
        "count":12,
        "page":1,
        "page_size":10
    },
}

4.2 詳情

GET http://.../goods/1

{
    "code":200,
    "msg":"SUCCESS",
    "data":{
        "detail":{"name":"番茄","price":"3.50"},
        "comments":[{"rank:5, "content":"五星好評(píng)"},{...}]
    },
}

4.3 POST或PUT驗(yàn)證失敗

POST http://.../goods -d '{"name":"番茄","price":"3.50"}'

{
    "code":406,
    "msg":"驗(yàn)證失敗, 請(qǐng)檢查是否按要求提交數(shù)據(jù)",
    "data":{
        "raw":{"name":"番茄","price":"3.50元"},  // 建議返回客戶端
        "errors":[{"price":["請(qǐng)輸入數(shù)字類型"]}]
    },
}

5.文件上傳與下載

上傳文件 HTTP 請(qǐng)求頭:

Content-Type:multipart/form-data

下載文件 HTTP 請(qǐng)求頭:

Content-Type:參見http://www.runoob.com/http/http-content-type.html

6.錯(cuò)誤碼

200 OK                      # 成功處理
400 Bad Request             # 客戶端請(qǐng)求有語法錯(cuò)誤,例如Content-Type與請(qǐng)求體不符或請(qǐng)求體無法解析
401 Unauthorized            # 請(qǐng)求未經(jīng)授權(quán),例如需要登陸
403 Forbidden               # 禁止操作該資源,例如權(quán)限不夠等
404 Not Found               # 請(qǐng)求資源不存在
405 Method Not Allowed      # 方法未允許
406 Not Acceptable          # 不可接受,未通過驗(yàn)證,不符合要求
408 Request Timeout         # 請(qǐng)求超時(shí)
500 Internal Server Error   # 服務(wù)器發(fā)生不可預(yù)期的錯(cuò)誤
503 Server Unavailable      # 服務(wù)器當(dāng)前不可用,一段時(shí)間后可能恢復(fù)正常,例如并發(fā)問題
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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