深入理解RESTful

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,)描述操作
圖片.png
  • 資源:操作的實(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:指定篩選條件沦童。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末仑濒,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子偷遗,更是在濱河造成了極大的恐慌墩瞳,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件氏豌,死亡現(xiàn)場離奇詭異喉酌,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)泵喘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門泪电,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人纪铺,你說我怎么就攤上這事相速。” “怎么了鲜锚?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵突诬,是天一觀的道長。 經(jīng)常有香客問我烹棉,道長攒霹,這世上最難降的妖魔是什么怯疤? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任浆洗,我火速辦了婚禮,結(jié)果婚禮上集峦,老公的妹妹穿的比我還像新娘伏社。我一直安慰自己,他們只是感情好塔淤,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布摘昌。 她就那樣靜靜地躺著,像睡著了一般高蜂。 火紅的嫁衣襯著肌膚如雪聪黎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天备恤,我揣著相機(jī)與錄音稿饰,去河邊找鬼锦秒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛喉镰,可吹牛的內(nèi)容都是我干的旅择。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼侣姆,長吁一口氣:“原來是場噩夢啊……” “哼生真!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起捺宗,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤柱蟀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蚜厉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體产弹,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年弯囊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了痰哨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡匾嘱,死狀恐怖斤斧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情霎烙,我是刑警寧澤撬讽,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站悬垃,受9級特大地震影響游昼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜尝蠕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一烘豌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧看彼,春花似錦廊佩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至茁计,卻和暖如春料皇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工践剂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留毒返,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓舷手,卻偏偏與公主長得像拧簸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子男窟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容