實(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ā)問題