什么是RESTful風(fēng)格的API

REST (REpresentational State Transfer)臭猜,直譯:表現(xiàn)層狀態(tài)轉(zhuǎn)移瓶珊。這個(gè)中文直譯經(jīng)常出現(xiàn)在很多文章中夹界。尼瑪戈次,誰(shuí)聽(tīng)得懂“表現(xiàn)層狀態(tài)轉(zhuǎn)移”轩勘,這是人話嗎?


那就逐個(gè)單詞來(lái)理解REST名稱(chēng)

REST -- REpresentational State Transfer
首先朝扼,之所以晦澀是因?yàn)榍懊娴闹髡Z(yǔ)被去掉了赃阀,全稱(chēng)是 Resource Representational State Transfer,通俗來(lái)講就是:資源在網(wǎng)絡(luò)中以某種表現(xiàn)形式進(jìn)行狀態(tài)轉(zhuǎn)移擎颖。

分解開(kāi)來(lái):
Resource:資源榛斯,即數(shù)據(jù)(前面說(shuō)過(guò)網(wǎng)絡(luò)的核心)。比如 newsfeed搂捧,friends等驮俗;
Representational:某種表現(xiàn)形式,比如用JSON允跑,XML王凑,JPEG等;
State Transfer:狀態(tài)變化聋丝。通過(guò)HTTP動(dòng)詞實(shí)現(xiàn)索烹。


為什么要用RESTful結(jié)構(gòu)呢?

大家都知道“古代”網(wǎng)頁(yè)是前端后端融在一起的弱睦,比如之前的PHP百姓,JSP等,在之前的桌面時(shí)代况木,前后端融合在一起沒(méi)啥問(wèn)題垒拢,但是近年來(lái)移動(dòng)互聯(lián)網(wǎng)的發(fā)展旬迹,各種類(lèi)型的Client層出不窮,RESTful可以通過(guò)一套統(tǒng)一的接口為Web求类、iOS奔垦、Android、小程序等提供接口API服務(wù)尸疆。另外對(duì)于廣大平臺(tái)來(lái)說(shuō)椿猎,比如Facebook platform,微博開(kāi)放平臺(tái)仓技,微信公共平臺(tái)等鸵贬,它們不需要有顯式的前端,只需要一套提供服務(wù)的接口脖捻,于是RESTful的API更是它們最好的選擇。


20171107171036253.jpeg

從原理角度來(lái)分析

根據(jù)Richardson Maturity Model(理查德森成熟度模型), REST架構(gòu)的成熟度有4個(gè)等級(jí):


20171107165849966.png

Level 0 - 面向前臺(tái)

我們?cè)诳Х鹊晗蚯芭_(tái)點(diǎn)了一杯拿鐵咖啡兆衅,這個(gè)過(guò)程可以用這段文字來(lái)描述:

{
    "addOrder": {
        "orderName": "latte"
    }
}

我們通過(guò)這段文字告訴前臺(tái)地沮,新增一筆訂單,訂單是一杯拿鐵咖啡羡亩,接著摩疑,前臺(tái)給我們返回這么一串回復(fù):

{
    "orderId": "123456"
}

假設(shè)我們有一張會(huì)員卡,我們想查詢一下這張會(huì)員卡的余額畏铆,這時(shí)候要向前臺(tái)發(fā)起另一個(gè)詢問(wèn):

{
    "queryBalance": {
        "cardId": "447031335"
    }
}

查詢卡號(hào)為447031335的卡的余額雷袋,查詢的結(jié)果返回來(lái)了:

{
    "balance": "0"
}

沒(méi)錢(qián)……哈哈哈,沒(méi)錢(qián)辞居,現(xiàn)在我們要跟前臺(tái)說(shuō)楷怒,這杯咖啡不要了:

{
    "deleteOrder": {
        "orderId": "123456"
    }
}

Level 1 - 面向資源

現(xiàn)在這家咖啡店越做越大,來(lái)喝咖啡的人越來(lái)越多瓦灶,單靠前臺(tái)顯然是不行的鸠删,店主決定進(jìn)行分工,每個(gè)資源都有專(zhuān)人負(fù)責(zé)贼陶,我們可以直接面向資源操作刃泡。
比如還是下單,請(qǐng)求的內(nèi)容不變碉怔,但是我們多了一條消息:

/orders
{
    "addOrder": {
        "orderName": "latte"
    }
}

多了一個(gè)斜杠和orders烘贴,這是什么意思?
這個(gè)表示我們這個(gè)請(qǐng)求是發(fā)給哪個(gè)資源的撮胧,訂單是一種資源桨踪,我們可以理解為是咖啡廳專(zhuān)門(mén)管理訂單的人,他可以幫我們處理所有有關(guān)訂單的操作趴樱,包括新增訂單馒闷、修改訂單酪捡、取消訂單等操作。
接著還是會(huì)返回訂單的編號(hào)給我們:

{
    "orderId": "123456"
}

下面纳账,我們還是要查詢會(huì)員卡余額逛薇,這次請(qǐng)求的資源變成了cards:

/cards
{
    "queryBalance": {
        "cardId": "447031335"
    }
}

接下來(lái)是取消訂單:

/orders
{
    "deleteOrder": {
        "orderId": "123456"
    }
}

Level 2 - 打上標(biāo)簽

接下來(lái),店主還想繼續(xù)優(yōu)化他的咖啡廳的服務(wù)流程疏虫,他發(fā)現(xiàn)負(fù)責(zé)處理訂單的員工永罚,每次都要去訂單內(nèi)容里面看是新增訂單還是刪除訂單,還是其他的什么操作卧秘,十分不方便呢袱,于是規(guī)定,所有新增資源的請(qǐng)求翅敌,都在請(qǐng)求上面寫(xiě)上大大的“POST”羞福,表示這是一筆新增資源的請(qǐng)求。
其他種類(lèi)的請(qǐng)求蚯涮,比如查詢類(lèi)的治专,用‘GET’表示,刪除類(lèi)的遭顶,用‘DELETE’表示张峰,修改用PATCH表示。
來(lái)棒旗,我們?cè)賮?lái)重復(fù)上面那個(gè)過(guò)程喘批,來(lái)一杯拿鐵:

POST /orders
{
    "orderName": "latte"
}

請(qǐng)求的內(nèi)容簡(jiǎn)潔多啦,不用告訴店員是addOrder铣揉,看到POST就知道是新增饶深,返回的內(nèi)容還是一樣:

{
    "orderId": "123456"
}

接著是查詢會(huì)員卡余額,這次也簡(jiǎn)化了很多:

GET /cards
{
    "cardId": "447031335"
}

這個(gè)請(qǐng)求我們還可以進(jìn)一步優(yōu)化為這樣:

GET /cards/447031335

直接把要查詢的卡號(hào)寫(xiě)在后面了老速。
沒(méi)錯(cuò)粥喜,接著,取消訂單:

DELETE /orders/123456

Level 3 - 完美服務(wù)

忽然有一天橘券,有個(gè)顧客抱怨說(shuō)额湘,他買(mǎi)了咖啡后,不知道要怎么取消訂單旁舰,咖啡廳一個(gè)店員回了一句锋华,你不會(huì)看我們的宣傳單嗎,上面不寫(xiě)著:

DELETE /orders/{orderId}

顧客反問(wèn)道箭窜,誰(shuí)會(huì)去看那個(gè)啊毯焕,店員不服,又說(shuō)到,你瞎了啊你……后面兩人吵著吵著還打了起來(lái)…
噗纳猫,真是悲劇…

有了這次教訓(xùn)婆咸,店長(zhǎng)決定,顧客下了單之后芜辕,不僅給他們返回訂單的編號(hào)尚骄,還給顧客返回所有可以對(duì)這個(gè)訂單做的操作,比如告訴用戶如何刪除訂單∏中現(xiàn)在倔丈,我們還是發(fā)出請(qǐng)求,請(qǐng)求內(nèi)容和上一次一樣:

POST /orders
{
    "orderName": "latte"
}

但是這次返回時(shí)多了些內(nèi)容:

{
    "orderId": "123456",
    "link": {
        "rel": "cancel",
        "url": "/order/123456"
    }
}

這次返回時(shí)多了一項(xiàng)link信息状蜗,里面包含了一個(gè)rel屬性和url屬性需五,rel是relationship的意思,這里的關(guān)系是cancel轧坎,url則告訴你如何執(zhí)行這個(gè)cancel操作宏邮,接著你就可以這樣子來(lái)取消訂單啦:

DELETE /orders/123456

哈哈,這服務(wù)真是貼心缸血,以后再也不用擔(dān)心店員和顧客打起來(lái)了蜀铲。
Level 3的Restful API,給使用者帶來(lái)了很大的便利属百,使用者只需要知道如何獲取資源的入口,之后的每個(gè)URI都可以通過(guò)請(qǐng)求獲得变姨,無(wú)法獲得就說(shuō)明無(wú)法執(zhí)行那個(gè)請(qǐng)求田轧。
現(xiàn)在絕大多數(shù)的RESTful接口都做到了Level2的層次舔糖,做到Level3的比較少。當(dāng)然,這個(gè)模型并不是一種規(guī)范辆飘,只是用來(lái)理解Restful的工具。所以湃望,做到了Level2驶赏,也就是面向資源和使用http動(dòng)詞,就已經(jīng)很Restful了爷辱。


Levels的意義

Level 1 解釋了如何通過(guò)分治法(Divide and Conquer)來(lái)處理復(fù)雜問(wèn)題录豺,將一個(gè)大型的服務(wù)端點(diǎn)(Service Endpoint)分解成多個(gè)資源。
Level 2 引入了一套標(biāo)準(zhǔn)的動(dòng)詞饭弓,用來(lái)以相同的方式應(yīng)對(duì)類(lèi)似的場(chǎng)景双饥,移除不要的變化。
Level 3 引入了可發(fā)現(xiàn)性(Discoverability)弟断,它可以使協(xié)議擁有自我描述(Self-documenting)的能力咏花。
這一模型幫助我們思考我們想要提供的HTTP服務(wù)是何種類(lèi)型的,同時(shí)也勾勒出人們和它進(jìn)行交互時(shí)的期望阀趴。


從應(yīng)用角度來(lái)分析

? REST描述的是在網(wǎng)絡(luò)中client和server的一種交互形式昏翰;REST本身不實(shí)用苍匆,實(shí)用的是如何設(shè)計(jì) RESTful API(REST風(fēng)格的網(wǎng)絡(luò)接口);

? Server提供的RESTful API中棚菊,URL中只使用名詞來(lái)指定資源浸踩,原則上不使用動(dòng)詞∏现辏“資源”是REST架構(gòu)或者說(shuō)整個(gè)網(wǎng)絡(luò)處理的核心民轴,
URL定位資源,用HTTP動(dòng)詞(GET/POST/DELETE/PATCH)來(lái)描述操作球订,

  1. 看url就知道要什么
  2. 看http method就知道干什么
  3. 看http status code就知道結(jié)果如何
    比如:
    http://api.qc.com/v1/newsfeed: 獲取某人的新鮮;
    http://api.qc.com/v1/friends: 獲取某人的好友列表;
    http://api.qc.com/v1/profile: 獲取某人的詳細(xì)信息;

? 用HTTP協(xié)議里的動(dòng)詞來(lái)實(shí)現(xiàn)資源的添加后裸、修改、刪除等操作冒滩。即通過(guò)HTTP動(dòng)詞來(lái)實(shí)現(xiàn)資源的狀態(tài)轉(zhuǎn)移:

  1. GET 用來(lái)獲取資源微驶,
  2. POST 用來(lái)新建資源(也可以用于更新資源),
  3. PUT 用來(lái)更新資源开睡,
  4. DELETE 用來(lái)刪除資源因苹。
    比如:
    DELETE http://api.qc.com/v1/friends: 刪除某人的好友 (在http parameter指定好友id)
    POST http://api.qc.com/v1/friends: 添加好友
    UPDATE http://api.qc.com/v1/profile: 更新個(gè)人資料

? Server和Client之間傳遞某資源的一個(gè)表現(xiàn)形式,比如用JSON篇恒,XML傳輸文本扶檐,或者用JPG,WebP傳輸圖片等胁艰。當(dāng)然還可以壓縮HTTP傳輸時(shí)的數(shù)據(jù)(on-wire data compression);

? 用 HTTP Status Code傳遞Server的狀態(tài)信息款筑。比如最常用的 200 表示成功,500 表示Server內(nèi)部錯(cuò)誤等腾么。

好了奈梳,理解了RESTful的概念,究竟如何應(yīng)用解虱,這是個(gè)問(wèn)題攘须。根據(jù)項(xiàng)目的需求不同,我們的API設(shè)計(jì)規(guī)范也存在差別殴泰,完全看自身理解于宙,滿足自身需求,大的理念不變艰匙,根據(jù)需求制定項(xiàng)目的API規(guī)范就是好的RESTful限煞。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市员凝,隨后出現(xiàn)的幾起案子署驻,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,348評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旺上,死亡現(xiàn)場(chǎng)離奇詭異瓶蚂,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)宣吱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)窃这,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人征候,你說(shuō)我怎么就攤上這事杭攻。” “怎么了疤坝?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,936評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵兆解,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我跑揉,道長(zhǎng)锅睛,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,427評(píng)論 1 283
  • 正文 為了忘掉前任历谍,我火速辦了婚禮现拒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘望侈。我一直安慰自己印蔬,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布脱衙。 她就那樣靜靜地躺著扛点,像睡著了一般。 火紅的嫁衣襯著肌膚如雪岂丘。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,785評(píng)論 1 290
  • 那天眠饮,我揣著相機(jī)與錄音奥帘,去河邊找鬼。 笑死仪召,一個(gè)胖子當(dāng)著我的面吹牛寨蹋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扔茅,決...
    沈念sama閱讀 38,931評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼已旧,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了召娜?” 一聲冷哼從身側(cè)響起运褪,我...
    開(kāi)封第一講書(shū)人閱讀 37,696評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后秸讹,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體檀咙,經(jīng)...
    沈念sama閱讀 44,141評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評(píng)論 2 327
  • 正文 我和宋清朗相戀三年璃诀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了弧可。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,625評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡劣欢,死狀恐怖棕诵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情凿将,我是刑警寧澤校套,帶...
    沈念sama閱讀 34,291評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站丸相,受9級(jí)特大地震影響搔确,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜灭忠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評(píng)論 3 312
  • 文/蒙蒙 一膳算、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧弛作,春花似錦涕蜂、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至萨西,卻和暖如春有鹿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谎脯。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工葱跋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人源梭。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓娱俺,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親废麻。 傳聞我的和親對(duì)象是個(gè)殘疾皇子荠卷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評(píng)論 2 348

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