REST是一種互聯(lián)網(wǎng)軟件架構(gòu)原則扮休,Representational State Transfer唇敞,翻譯為表現(xiàn)層狀態(tài)轉(zhuǎn)化约急。如果一個(gè)架構(gòu)符合REST原則筋栋,就稱它為RESTful架構(gòu)炊汤。
本文目的——設(shè)計(jì)符合RESTful 規(guī)范的API
1 看Url就知道要什么
2 看http method就知道干什么
3 看http status code就知道結(jié)果如何
RESTful的作用與優(yōu)點(diǎn)
制定一套符合標(biāo)準(zhǔn),容易理解弊攘,可讀性高抢腐,易于協(xié)作的API規(guī)范。
現(xiàn)在的web應(yīng)用襟交,我們完全可以理解為是一種軟件迈倍,是一種互聯(lián)網(wǎng)軟件。這種互聯(lián)網(wǎng)軟件捣域,有別于傳統(tǒng)軟件啼染,采用客戶端/服務(wù)端模式宴合,建立在分布式體系上,通過互聯(lián)網(wǎng)通信迹鹅。REST架構(gòu)卦洽,就是在符合架構(gòu)原理的前提下,以網(wǎng)絡(luò)為基礎(chǔ)的應(yīng)用軟件的架構(gòu)設(shè)計(jì)斜棚,它結(jié)構(gòu)清晰阀蒂、符合標(biāo)準(zhǔn)、易于理解弟蚀、擴(kuò)展方便蚤霞,所以正得到越來越多網(wǎng)站的采用。
區(qū)別于傳統(tǒng)的軟件粗梭,網(wǎng)絡(luò)通信是這種互聯(lián)網(wǎng)軟件的核心争便,RESTful架構(gòu)所提供的RESTful API 標(biāo)準(zhǔn)明確级零,可讀性高断医,易于理解,靈活可擴(kuò)展奏纪,為客戶端服鉴嗤,務(wù)端的通信提供了良好的解決方案。
互聯(lián)網(wǎng)公司面臨多重挑戰(zhàn):一方面智能手機(jī)序调,平板電腦這些移動設(shè)備層出不窮醉锅,需要支持這些設(shè)備,即我們的web和移動端都可以調(diào)用相同的接口发绢;另一方面無論是公司內(nèi)部的數(shù)據(jù)互通(微服務(wù)間的通信)還是和外部合作(暴露接口給第三方)硬耍,都需要展示相同的業(yè)務(wù)邏輯。現(xiàn)在越來越多公司采用的策略是边酒,讓服務(wù)端所有商業(yè)邏輯RESTful API 的方式暴露給客戶端经柴,瀏覽器可以使用Ajax、HTML5等技術(shù)墩朦,通過HTTP的方式與后臺直接交互坯认,即做到前后端分離。這種開發(fā)機(jī)制有很好的擴(kuò)展性氓涣,又減少了開發(fā)復(fù)雜度牛哺。
理解RESTful
URL定位資源,用HTTP動詞(GET,POST,PUT,DELETE,)描述操作
資源:操作的實(shí)體對象劳吠。REST的名稱"表現(xiàn)層狀態(tài)轉(zhuǎn)化"中引润,省略了主語。"表現(xiàn)層"其實(shí)指的是"資源"(Resources)的"表現(xiàn)層"痒玩。所謂"資源"椰拒,就是網(wǎng)絡(luò)上的一個(gè)實(shí)體晶渠,或者說是網(wǎng)絡(luò)上的一個(gè)具體信息。它可以是一段文本燃观、一張圖片褒脯、一首歌曲、一種服務(wù)缆毁,總之就是一個(gè)具體的實(shí)在番川。你可以用一個(gè)URI(統(tǒng)一資源標(biāo)識符)指向資源,可以使用HTTP請求方法操作資源脊框。URI可以進(jìn)一步劃分為統(tǒng)一資源名URN(代表資源的名稱颁督,定義資源的身份),統(tǒng)一資源定位符URL(代表資源的地址浇雹,提供查找該資源的方式)沉御。我們定位互聯(lián)網(wǎng)上的一個(gè)資源普遍采用的就是URL。例如 http://www.pythondoc.com/flask/index.html 該URL就定位到flask的中文官方文檔昭灵,而這個(gè)文檔文件就是一個(gè)資源吠裆。
表現(xiàn)層:資源的表現(xiàn)形式, "資源"是一種信息實(shí)體烂完,它可以有多種外在表現(xiàn)形式试疙。我們把"資源"具體呈現(xiàn)出來的形式,叫做它的"表現(xiàn)層"(Representation)抠蚣。比如祝旷,文本可以用txt格式表現(xiàn),也可以用HTML格式嘶窄、XML格式怀跛、JSON格式表現(xiàn),甚至可以采用二進(jìn)制格式柄冲;圖片可以用JPG格式表現(xiàn)吻谋,也可以用PNG格式表現(xiàn)。URI只代表資源的實(shí)體羊初,不代表它的形式滨溉。嚴(yán)格地說,有些網(wǎng)址最后的".html"后綴名是不必要的长赞,因?yàn)檫@個(gè)后綴名表示格式晦攒,屬于"表現(xiàn)層"范疇,而URL應(yīng)該只代表"資源"的位置得哆。它的具體表現(xiàn)形式脯颜,應(yīng)該在HTTP請求的頭信息中用Accept(能夠接受的的數(shù)據(jù)類型)和Content-Type(POST和PUT請求的數(shù)據(jù)類型)字段指定,這兩個(gè)字段才是對"表現(xiàn)層"的描述贩据。通俗講栋操,我這個(gè)資源應(yīng)該以什么形式展示給客戶端闸餐,像我們系統(tǒng)在POST請求的時(shí)候請求頭中,Accept:application/json 矾芙,text/plain 舍沙,/和Content-Type:application/json ,我們規(guī)定了JSON 的資源表示形式剔宪。
狀態(tài)轉(zhuǎn)化:讓服務(wù)端的資源進(jìn)行變化拂铡。訪問一個(gè)資源,代表著客戶端與服務(wù)器的一個(gè)互動過程葱绒。在這個(gè)過程中勢必涉及到數(shù)據(jù)變化感帅。如果客戶端想
讓服務(wù)端數(shù)據(jù)發(fā)生變化,用到HTTP協(xié)議里面表示操作方式的動詞:GET地淀、POST失球、PUT、DELETE帮毁。它們分別對應(yīng)四種基本操作:GET用來獲取資源实苞,POST用來新建資源(也可以用于更新資源),PUT用來更新資源作箍,DELETE用來刪除資源硬梁。HTTP Status Code傳遞Server的狀態(tài)信息前硫。該服務(wù)是否有效胞得,該操作是否被服務(wù)端正確執(zhí)行,是通過Status Code表示的屹电。比如最常用的 200 表示成功阶剑,500 表示Server內(nèi)部錯誤等。如果出錯則返回錯誤信息和 400 BadRequest危号,由客戶端處理異常牧愁。
綜述
(1)每一個(gè)URL代表一種資源;
(2)客戶端和服務(wù)器之間外莲,傳遞這種資源的某種表現(xiàn)層猪半;
(3)客戶端通過四個(gè)HTTP動詞,對服務(wù)器端資源進(jìn)行操作偷线,實(shí)現(xiàn)"表現(xiàn)層狀態(tài)轉(zhuǎn)化"磨确。
RESTful API 設(shè)計(jì)規(guī)范
API一旦發(fā)布,其結(jié)構(gòu)將很難修改声邦,因此設(shè)計(jì)一個(gè)符合規(guī)范乏奥,靈活友好的API,是一件非常重要的事情亥曹。
以資源為中心的 URL 設(shè)計(jì)
-
資源是 Restful API 的核心元素邓了,所有的操作都是針對特定資源進(jìn)行的恨诱。
/users
/users/1
/tasks
/users/tasks
/users/tasks/1
使用名詞來表示資源
-
URL不應(yīng)該包含動詞。動詞應(yīng)該通過不同的HTTP方法來體現(xiàn)
常見錯誤用法
POST /users/1/create
POST /users/1/delete
正確的用法為
GET /users
GET /users/1
PUT /users/1
關(guān)注請求頭
- 一定要看請求頭的信息骗炉,并且給予正確的狀態(tài)碼照宝。假設(shè)服務(wù)器端只能返回JSON格式,如果客戶端的頭信息的Accept字段要求返回application/xml句葵,這個(gè)時(shí)候就不應(yīng)該返回application/json類型的數(shù)據(jù)硫豆,而是返回406 錯誤信息。
合理使用請求方法笼呆、狀態(tài)碼和返回信息熊响。
GET(SELECT):用于從服務(wù)器獲取資源信息(一項(xiàng)或多項(xiàng))。
1 完成請求后诗赌,返回狀態(tài)碼200 OK
2 查詢多項(xiàng)汗茄,完成請求后,返回被請求資源的列表(對象組成的數(shù)組)
3 查詢一項(xiàng)铭若,完成請求后洪碳,返回被請求資源的詳情(對象)POST(CREATE):用于在服務(wù)器新建一個(gè)資源。
1 創(chuàng)建完成后叼屠,返回狀態(tài)碼201 Created
2 完成請求后瞳腌,返回被創(chuàng)建資源的詳細(xì)信息PUT(UPDATE):用于完整的替換資源或者創(chuàng)建指定身份的資源,比如創(chuàng)建id為123的某個(gè)資源镜雨。
1 如果創(chuàng)建了資源嫂侍,則返回201 Created
2 如果替換了資源,則返回200 OK
3 返回被修改資源的詳細(xì)信息DELETE(DELETE):用于從服務(wù)器刪除資源荚坞。
刪除成功挑宠,返回狀態(tài)碼 204 No Content
如未完成查詢,創(chuàng)建颓影,更新各淀,刪除等不符合預(yù)期的操,即客戶端發(fā)出的請求有錯誤诡挂,返回定義好的錯誤信息并且返回錯誤碼400 Bad Request
還有幾個(gè)不常用的方法
- PATCH(UPDATE):用于局部更新資源碎浇。
- HEAD:獲取資源的元數(shù)據(jù)。
- OPTIONS:獲取資源支持的所有HTTP方法璃俗。
保證返回結(jié)果具有高可讀性
對輸出結(jié)果不在包裝
body中應(yīng)該直接放數(shù)據(jù)奴璃,不要多層封裝
錯誤例子
HTTP/1.1 200 OK
{
"success":"true",
"data":{
"id":1,
"name":"chaozi"
}
}
正確的例子應(yīng)該是
HTTP/1.1 200 OK
{
"id":1,
"name":"chaozi"
}
使用嵌套對象序列化
對象應(yīng)該合理嵌套,不應(yīng)該都在一個(gè)層次上旧找。如下格式是不正確的
{
"id":1,
"author":"chaozi",
"artical_id":"1001",
"artical_name":"artical1",
"artical_content":"this is a artical"
}
把相關(guān)聯(lián)的資源信息內(nèi)聯(lián)在一起溺健。應(yīng)該把a(bǔ)rtical作為一個(gè)鍵
{
"id":1,
"author":"chaozi",
"artical":{
"id":"10001",
"name":"artical1",
"content":"this is a artical"
}
}
信息過濾
URL 通常越簡潔越好,對結(jié)果的過濾,排序和搜索都應(yīng)該通過參數(shù)實(shí)現(xiàn)
?limit=10:指定返回記錄的數(shù)量鞭缭。
?offset=10:指定返回記錄的開始位置剖膳。
?page=2&per_page=100:指定第幾頁,以及每頁的記錄數(shù)岭辣。
?sortby=name&order=asc:指定返回結(jié)果按照哪個(gè)屬性排序吱晒,以及排序順序。
?animal_type_id=1:指定篩選條件沦童。