REST風(fēng)格接口學(xué)習(xí)

REST 簡介

大佬繞路,小白多篇文章整合總結(jié)篇

REST 是一個(gè)術(shù)語的縮寫词疼,REpresentational State Transfer,中文直譯「表征狀態(tài)轉(zhuǎn)移」蝶涩。這只是一個(gè)名字而已不必強(qiáng)行解釋概念,關(guān)鍵是這個(gè)東西它干了什么窜司,直接看怎么做,根據(jù)大佬講有了一定項(xiàng)目經(jīng)驗(yàn)再來看名字會有更深刻的理解惠桃。REST 是一套風(fēng)格約定,RESTful 是它的形容詞形式辖试;比如一套實(shí)現(xiàn)了 REST 風(fēng)格的接口辜王,可以稱之為 RESTful 接口。

REST 對請求的約定

REST 用來規(guī)范應(yīng)用如何在 HTTP 層與 API 提供方進(jìn)行數(shù)據(jù)交互罐孝;在現(xiàn)階段呐馆,在對于學(xué)過JavaWeb的時(shí)候來說是基本寫過使用servlet的管理系統(tǒng),因此你應(yīng)該已經(jīng)很熟悉 GET 和 POST 請求;甚至有可能因?yàn)槭芟抻诤蠖丝蚣芟拗频仍蛏龅担愕恼麄€(gè)應(yīng)用全都是用這兩種 HTTP 方法來完成的摹恰。這樣無疑浪費(fèi)了 HTTP 協(xié)議的潛力,而 REST 則充分利用了 HTTP 規(guī)范中的方法怒见,達(dá)到接口描述的語義化俗慈。

REST 描述了 HTTP 層里客戶端和服務(wù)器端的數(shù)據(jù)交互規(guī)則;客戶端通過向服務(wù)器端發(fā)送 HTTP(s)請求遣耍,接收服務(wù)器的響應(yīng)闺阱,完成一次 HTTP 交互。這個(gè)交互過程中舵变,REST 架構(gòu)約定兩個(gè)重要方面就是 HTTP 請求的所采用方法酣溃,以及請求的鏈接瘦穆。

在請求層面,REST 規(guī)范可以簡單粗暴抽象成以下兩個(gè)規(guī)則:

\1. 請求 API 的 URL 表示用來定位資源赊豌;

\2. 請求的 METHOD 表示對這個(gè)資源進(jìn)行的操作扛或;

以下將以這兩個(gè)規(guī)則為基礎(chǔ),描述如何構(gòu)造一個(gè)符合 REST 規(guī)范的請求碘饼。

一熙兔、API 的 URL

URL 用來定位資源,跟要進(jìn)行的操作區(qū)分開艾恼,這就意味這 URL 不該有任何動詞住涉;

下面示例中的 get、create钠绍、search 等動詞舆声,都不應(yīng)該出現(xiàn)在 REST 架構(gòu)的后端接口路徑中。在以前柳爽,這些接口中的動名詞通常對應(yīng)后臺的某個(gè)函數(shù)媳握。比如:

/api/getUser
/api/createApp
/api/searchResult
/api/deleteAllUsers

當(dāng)我們需要對單個(gè)用戶進(jìn)行操作時(shí),根據(jù)操作的方式不同可能需要下面的這些接口:

/api/getUser (用來獲取某個(gè)用戶的信息磷脯,還需要以參數(shù)方式傳入用戶 id 信息)
/api/updateUser (用來更新用戶信息)
/api/deleteUser (用來刪除單個(gè)用戶)
/api/resetUser (重置用戶的信息)

更有甚者毙芜,可能在更新用戶不同信息時(shí),提供不同的接口争拐,比如:

/api/updateUserName
/api/updateUserEmail
/api/updateUser

這樣的弊端在于:首先加上了動詞,肯定是使 URL 更長了晦雨;其次對一個(gè)資源實(shí)體進(jìn)行不同的操作就是一個(gè)不同的 URL架曹,造成 URL 過多難以管理。

其實(shí)當(dāng)你回過頭看「URL」 這個(gè)術(shù)語的定義時(shí)闹瞧,更能理解這一點(diǎn)绑雄。URL 的意思是統(tǒng)一資源定位符,這個(gè)術(shù)語已經(jīng)清晰的表明奥邮,一個(gè) URL 應(yīng)該用來定位資源万牺,而不應(yīng)該摻入對操作行為的描述。

在 REST 架構(gòu)的鏈接應(yīng)該是這個(gè)樣子:

  1. URL 中不應(yīng)該出現(xiàn)任何表示操作的動詞洽腺,鏈接只用于對應(yīng)資源脚粟;
  2. URL 中應(yīng)該單復(fù)數(shù)區(qū)分,推薦的實(shí)踐是永遠(yuǎn)只用復(fù)數(shù)蘸朋;比如 GET /api/users 表示獲取用戶的列表核无;如果獲取單個(gè)資源,傳入 ID藕坯,比如 /api/users/123 表示獲取單個(gè)用戶的信息团南;
  3. 按照資源的邏輯層級噪沙,對 URL 進(jìn)行嵌套,比如一個(gè)用戶屬于某個(gè)團(tuán)隊(duì)吐根,而這個(gè)團(tuán)隊(duì)也是眾多團(tuán)隊(duì)之一正歼;那么獲取這個(gè)用戶的接口可能是這樣:
GET /api/teams/123/members/234 表示獲取 id 為 123 的小組下,id 為234 的成員信息

按照類似的規(guī)則拷橘,可以寫出如下的接口

/api/teams (對應(yīng)團(tuán)隊(duì)列表)
/api/teams/123 (對應(yīng) ID 為 123 的團(tuán)隊(duì))
/api/teams/123/members (對應(yīng) ID 為 123 的團(tuán)隊(duì)下的成員列表)
/api/teams/123/members/456 (對應(yīng) ID 為 123 的團(tuán)隊(duì)下 ID 未 456 的成員)

二局义、API 請求的方法

在很多系統(tǒng)中,幾乎只用 GET 和 POST 方法來完成了所有的接口操作膜楷;這個(gè)行為類似于全用 DIV 來布局旭咽。實(shí)際上,我們不只有GET 和 POST 可用赌厅,在 REST 架構(gòu)中穷绵,有以下幾個(gè)重要的請求方法:GET,POST特愿,PUT仲墨,PATCH,DELETE揍障。這幾個(gè)方法都可以與對數(shù)據(jù)的 CRUD 操作對應(yīng)起來目养。

【Read】,資源的讀取毒嫡,用 GET 請求癌蚁;比如:

GET /api/users  ( 表示讀取用戶列表)

GET 應(yīng)當(dāng)實(shí)現(xiàn)為一個(gè)安全方法。用于獲取數(shù)據(jù)而不應(yīng)該產(chǎn)生副作用兜畸。

【Created】努释,資源的創(chuàng)建,用 POST 方法咬摇;

POST 是一個(gè)冪等的方法伐蒂,多次調(diào)用會造成不同效果;

冪等(Idempotent):如果對服務(wù)器資源的多次請求與一次請求造成的副作用是一樣的的話肛鹏,那這個(gè)請求方法可以被認(rèn)為是冪等逸邦。

比如下面的請求會在服務(wù)器上創(chuàng)建一個(gè) name 屬性為 'John Snow' 的用戶;多次請求就會創(chuàng)建多個(gè)這樣的用戶在扰。

POST /api/users
{
  "name": "John Snow"
}

【Update】缕减,資源的更新。用于更新的 HTTP 方法有兩個(gè)健田,PUT 和 PATCH烛卧。

他們都應(yīng)當(dāng)被實(shí)現(xiàn)為冪等方法,即多次同樣的更新請求應(yīng)當(dāng)對服務(wù)器產(chǎn)生同樣的副作用。

PUT 和 PATCH 有各自不同的使用場景:

PUT 用于更新資源的全部信息总放,在請求的 body 中需要傳入修改后的全部資源主體呈宇;

而 PATCH 用于局部更新,在 body 中只需要傳入需要改動的資源字段局雄。

設(shè)想服務(wù)器中有以下用戶資源 /api/users/123

{
 "id": 123,
 "name": "Original",
 "age": 20
}

當(dāng)我們往后臺發(fā)送更新請求時(shí)甥啄,PATCH 和 PUT 造成的效果是不一樣。

PUT /api/users/123
{
 "name": "PUT Update"
}

上述 PUT 請求操作后的內(nèi)容是:

{
 "id": 123,
 "name": "PUT Update"
}

可以觀察到炬搭,資源原有的 age 字段被清除掉了蜈漓。

而如果改用 PATCH 的話,

PATCH /api/users/123
{
 "name": "PATCH Update"
}

更新后的內(nèi)容是:

{
 "id": 123,
 "name": "PATCH Update",
 "age": 20
}

請求中指定的 name 屬性被更新了宫盔,而原有的 age 屬性則保持不變融虽。

PATCH 的作用在于如果一個(gè)資源有很多字段,在進(jìn)行局部更新時(shí)灼芭,只需要傳入需要修改的字段即可有额。否則在用 PUT 的情況下,你不得不將整個(gè)資源模型全都發(fā)送回服務(wù)器彼绷,造成網(wǎng)絡(luò)資源的極大浪費(fèi)巍佑。

【Delete】,資源的刪除寄悯,相應(yīng)的請求 HTTP 方法就是 DELETE萤衰。這個(gè)也應(yīng)當(dāng)被實(shí)現(xiàn)為一個(gè)冪等的方法。如:

DELETE /api/users/123

用于刪除服務(wù)器上 ID 為 123 的資源猜旬,多次請求產(chǎn)生副作用都是脆栋,是服務(wù)器上 ID 為 123 的資源不存在。

三洒擦、分頁筹吐、過濾

REST 風(fēng)格的接口地址,表示的可能是單個(gè)資源秘遏,也可能是資源的集合;當(dāng)我們需要訪問資源集合時(shí)嘉竟,設(shè)計(jì)良好的接口應(yīng)當(dāng)接受參數(shù)邦危,允許只返回滿足某些特定條件的資源列表。

比如支持以 offset 和 limit 參數(shù)來進(jìn)行分頁舍扰;

GET /api/users?offset=0&limit=20

支持提供關(guān)鍵詞進(jìn)行搜索倦蚪,以及排序

GET /api/users?keyword=john&sort=age

支持根據(jù)字段進(jìn)行過濾

GET /api/users?gender=male

設(shè)計(jì)合適的 API URL,以及選擇合適的請求方法边苹,可以語義化的描述一個(gè) HTTP 請求的操作陵且。

當(dāng)我們都熟悉且遵循這樣的規(guī)范后,基本可以看到一個(gè) REST 風(fēng)格的接口就知道如何使用這個(gè)接口進(jìn)行 CRUD 操作了。比如下面這面這個(gè)接口就表示搜索 ID 為 123 的圖書館的書慕购,并且書的信息里包含關(guān)鍵字「game」聊疲,返回前十條滿足條件的結(jié)果。

GET /api/libraries/123/books?keyword=game&sort=price&limit=10&offset=0

同樣沪悲,下面這個(gè)請求的意思也就很明顯了吧获洲。

PATCH /api/companies/123/employees/234
{
    "salary": 2300
}

請求類型總結(jié)

GET(SELECT):從服務(wù)器取出資源(一項(xiàng)或多項(xiàng))。
POST(CREATE):在服務(wù)器新建一個(gè)資源殿如。
PUT(UPDATE):在服務(wù)器更新資源(客戶端提供改變后的完整資源)贡珊。
PATCH(UPDATE):在服務(wù)器更新資源(客戶端提供改變的屬性)。
DELETE(DELETE):從服務(wù)器刪除資源涉馁。
還有兩個(gè)不常用的請求
HEAD:獲取資源的元數(shù)據(jù)门岔。
OPTIONS:獲取信息,關(guān)于資源的哪些屬性是客戶端可以改變的烤送。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末寒随,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子胯努,更是在濱河造成了極大的恐慌牢裳,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叶沛,死亡現(xiàn)場離奇詭異蒲讯,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)灰署,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門判帮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人溉箕,你說我怎么就攤上這事晦墙。” “怎么了肴茄?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵晌畅,是天一觀的道長。 經(jīng)常有香客問我寡痰,道長抗楔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任拦坠,我火速辦了婚禮连躏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘贞滨。我一直安慰自己入热,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著勺良,像睡著了一般绰播。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上郑气,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天幅垮,我揣著相機(jī)與錄音,去河邊找鬼尾组。 笑死忙芒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的讳侨。 我是一名探鬼主播呵萨,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼跨跨!你這毒婦竟也來了潮峦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤勇婴,失蹤者是張志新(化名)和其女友劉穎忱嘹,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體耕渴,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拘悦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了橱脸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片础米。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖添诉,靈堂內(nèi)的尸體忽然破棺而出屁桑,到底是詐尸還是另有隱情,我是刑警寧澤栏赴,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布蘑斧,位于F島的核電站,受9級特大地震影響须眷,放射性物質(zhì)發(fā)生泄漏乌叶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一柒爸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧事扭,春花似錦捎稚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽葡公。三九已至,卻和暖如春条霜,著一層夾襖步出監(jiān)牢的瞬間催什,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工宰睡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蒲凶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓拆内,卻偏偏與公主長得像旋圆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子麸恍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353