一故慈、API
API -- Application Programming Interface辫塌,即應(yīng)用程序編程接口逆皮。
它是一些預(yù)先定義的函數(shù)由蘑,目的是提供應(yīng)用程序與開發(fā)人員基于某軟件或硬件得以訪問一組例程的能力辽装,而又無需訪問源碼帮碰,或理解內(nèi)部工作機(jī)制的細(xì)節(jié)。
二如迟、REST(RESTful)
REST -- Representational State Transfer收毫,即表現(xiàn)層狀態(tài)轉(zhuǎn)換。
它是由 Roy Thomas Fielding 博士于2000年提出來的一種萬維網(wǎng)軟件架構(gòu)風(fēng)格殷勘,目的是便于不同軟件/程序在網(wǎng)絡(luò)(例如互聯(lián)網(wǎng))中互相傳遞信息此再。
它是根基于超文本傳輸協(xié)議(HTTP)之上而確定的一組約束和屬性,是一種設(shè)計(jì)提供萬維網(wǎng)絡(luò)服務(wù)的軟件構(gòu)建風(fēng)格玲销。匹配或兼容于這種架構(gòu)風(fēng)格(簡(jiǎn)稱為 REST 或 RESTful)的網(wǎng)絡(luò)服務(wù)输拇,允許客戶端發(fā)出以統(tǒng)一資源標(biāo)識(shí)符訪問和操作網(wǎng)絡(luò)資源的請(qǐng)求,而與預(yù)先定義好的無狀態(tài)操作集一致化贤斜。
因此表現(xiàn)層狀態(tài)轉(zhuǎn)換提供了在互聯(lián)網(wǎng)絡(luò)的計(jì)算系統(tǒng)之間策吠,彼此資源可交互使用的協(xié)作性質(zhì)(interoperability)。相對(duì)于其它種類的網(wǎng)絡(luò)服務(wù)瘩绒,例如 SOAP服務(wù)則是以本身所定義的操作集猴抹,來訪問網(wǎng)絡(luò)上的資源。
【注】REST是設(shè)計(jì)風(fēng)格而不是標(biāo)準(zhǔn)锁荔。
REST 通丑案基于使用 HTTP、URI 和 XML 以及 HTML 這些現(xiàn)有的廣泛流行的協(xié)議和標(biāo)準(zhǔn)。
- 資源是由URI來指定跋理。
- 對(duì)資源的操作包括獲取择克、創(chuàng)建、修改和刪除資源前普,這些操作正好對(duì)應(yīng) HTTP 協(xié)議提供的 GET肚邢、POST、PUT 和 DELETE 方法拭卿。
- 通過操作資源的表現(xiàn)形式來操作資源骡湖。
- 資源的表現(xiàn)形式則是 XML 或者 HTML,取決于讀者是機(jī)器還是人峻厚,是消費(fèi) web 服務(wù)的客戶軟件還是 web 瀏覽器勺鸦。當(dāng)然也可以是任何其他的格式。
REST 指的是一組架構(gòu)約束條件和原則目木,而滿足這些約束條件和原則的應(yīng)用程序或設(shè)計(jì)就是 RESTful。
三懊渡、RESTful API
所以 RESTful API 就是 REST 風(fēng)格的 API刽射。
那么在什么場(chǎng)景下使用 RESTful API 呢?在當(dāng)今的互聯(lián)網(wǎng)應(yīng)用的前端展示媒介很豐富剃执,有手機(jī)誓禁、有平板電腦還有 PC 以及其他的展示媒介。那么這些前端接收到的用戶請(qǐng)求統(tǒng)一由一個(gè)后臺(tái)來處理并返回給不同的前端肯定是最科學(xué)和最經(jīng)濟(jì)的方式肾档,RESTful API 就是一套協(xié)議來規(guī)范多種形式的前端和同一個(gè)后臺(tái)的交互方式摹恰。
RESTful API 由后臺(tái)也就是 SERVER 來提供前端來調(diào)用。前端調(diào)用API 向后臺(tái)發(fā)起 HTTP 請(qǐng)求怒见,后臺(tái)響應(yīng)請(qǐng)求將處理結(jié)果反饋給前端俗慈。也就是說 RESTful 是典型的基于 HTTP 的協(xié)議。那么RESTful API有哪些設(shè)計(jì)原則和規(guī)范呢遣耍?
四闺阱、RESTful API 設(shè)計(jì)
1、資源
首先是弄清楚資源的概念舵变,資源就是網(wǎng)絡(luò)上的一個(gè)實(shí)體酣溃,一段文本,一張圖片或者一首歌曲纪隙。資源總是要通過一種載體來反應(yīng)它的內(nèi)容赊豌。文本可以用 TXT,也可以用 HTML 或者 XML绵咱,圖片可以用 JPG 格式或者 PNG 格式碘饼,JSON 是現(xiàn)在最常用的資源表現(xiàn)形式。
2、統(tǒng)一接口
RESTful 風(fēng)格的數(shù)據(jù)元操 CRUD(create派昧、read黔姜、update、delete)分別對(duì)應(yīng) HTTP 方法:GET 用來獲取資源蒂萎,POST 用來新建資源(也可以用于更新資源)秆吵,PUT 用來更新資源,DELETE 用來刪除資源五慈,這樣就統(tǒng)一了數(shù)據(jù)操作的接口纳寂。
3、URI
可以用一個(gè) URI(統(tǒng)一資源定位符)指向資源泻拦,即每個(gè) URI 都對(duì)應(yīng)一個(gè)特定的資源毙芜。要獲取這個(gè)資源訪問它的 URI 就可以,因此 URI 就成了每一個(gè)資源的地址或識(shí)別符争拐。一般的腋粥,每個(gè)資源至少有一個(gè) URI 與之對(duì)應(yīng),最典型的 URI 就是 URL架曹。
4隘冲、無狀態(tài)
所謂無狀態(tài)即所有的資源都可以 URI 定位,而且這個(gè)定位與其他資源無關(guān)绑雄,也不會(huì)因?yàn)槠渌Y源的變化而變化展辞。有狀態(tài)和無狀態(tài)的區(qū)別,舉個(gè)例子說明一下万牺,例如要查詢員工工資的步驟為第一步:登錄系統(tǒng)罗珍。第二步:進(jìn)入查詢工資的頁面。第三步:搜索該員工脚粟。第四步:點(diǎn)擊姓名查看工資覆旱。這樣的操作流程就是有狀態(tài)的,查詢工資的每一個(gè)步驟都依賴于前一個(gè)步驟核无,只要前置操作不成功通殃,后續(xù)操作就無法執(zhí)行。如果輸入一個(gè) URL 就可以得到指定員工的工資厕宗,則這種情況就是無狀態(tài)的画舌,因?yàn)楂@取工資不依賴于其他資源或狀態(tài),且這種情況下已慢,員工工資是一個(gè)資源曲聂,由一個(gè) URL 與之對(duì)應(yīng)可以通過 HTTP 中的 GET 方法得到資源,這就是典型的 RESTful 風(fēng)格佑惠。
五朋腋、RESTful API 設(shè)計(jì)細(xì)節(jié)
1齐疙、協(xié)議
API 與用戶的通信協(xié)議,總是使用 HTTPs 協(xié)議旭咽。
2贞奋、域名
應(yīng)該盡量將 API 部署在專用域名之下。
如果確定 API 很簡(jiǎn)單穷绵,不會(huì)有進(jìn)一步擴(kuò)展轿塔,可以考慮放在主域名下。
3仲墨、版本
應(yīng)該將 API 的版本號(hào)放入 URL勾缭。
另一種做法是,將版本號(hào)放在 HTTP 頭信息中目养,但不如放入 URL 方便和直觀俩由。Github 采用這種做法。
4癌蚁、路徑
路徑又稱“終點(diǎn)”(endpoint)幻梯,表示 API 的具體網(wǎng)址。
在 RESTful 架構(gòu)中努释,每個(gè)網(wǎng)址代表一種資源(resource)礼旅,所以網(wǎng)址中不能有動(dòng)詞,只能有名詞洽洁,而且所用的名詞往往與數(shù)據(jù)庫的表格名對(duì)應(yīng)。一般來說菲嘴,數(shù)據(jù)庫中的表都是同種記錄的“集合”(collection)饿自,所以 API 中的名詞也應(yīng)該使用復(fù)數(shù)。
舉例來說龄坪,有一個(gè) API 提供動(dòng)物園(zoo)的信息昭雌,還包括各種動(dòng)物和雇員的信息,則它的路徑應(yīng)該設(shè)計(jì)成下面這樣:
5健田、HTTP 動(dòng)詞
對(duì)于資源的具體操作類型烛卧,由 HTTP 動(dòng)詞表示。
常用的 HTTP 動(dòng)詞有下面五個(gè)(括號(hào)里是對(duì)應(yīng)的 SQL 命令):
- GET(SELECT):從服務(wù)器取出資源(一項(xiàng)或多項(xiàng))妓局。
- POST(CREATE):在服務(wù)器新建一個(gè)資源总放。
- PUT(UPDATE):在服務(wù)器更新資源(客戶端提供改變后的完整資源)。
- PATCH(UPDATE):在服務(wù)器更新資源(客戶端提供改變的屬性)好爬。
- DELETE(DELETE):從服務(wù)器刪除資源局雄。
還有兩個(gè)不常用的 HTTP 動(dòng)詞:
- HEAD:獲取資源的元數(shù)據(jù)。
- OPTIONS:獲取信息存炮,關(guān)于資源的哪些屬性是客戶端可以改變的炬搭。
下面是一些例子:
-GET /zoos:列出所有動(dòng)物園
- POST /zoos:新建一個(gè)動(dòng)物園
- GET /zoos/ID:獲取某個(gè)指定動(dòng)物園的信息
- PUT /zoos/ID:更新某個(gè)指定動(dòng)物園的信息(提供該動(dòng)物園的全部信息)
- PATCH /zoos/ID:更新某個(gè)指定動(dòng)物園的信息(提供該動(dòng)物園的部分信息)
- DELETE /zoos/ID:刪除某個(gè)動(dòng)物園
- GET /zoos/ID/animals:列出某個(gè)指定動(dòng)物園的所有動(dòng)物
- DELETE /zoos/ID/animals/ID:刪除某個(gè)指定動(dòng)物園的指定動(dòng)物
六蜈漓、過濾信息
如果記錄數(shù)量很多,服務(wù)器不可能都將它們返回給用戶宫盔。API 應(yīng)該提供參數(shù)融虽,過濾返回結(jié)果。
下面是一些常見的參數(shù):
- ?limit=10:指定返回記錄的數(shù)量
- ?offset=10:指定返回記錄的開始位置灼芭。
- ?page=2&per_page=100:指定第幾頁有额,以及每頁的記錄數(shù)。
- ?sortby=name&order=asc:指定返回結(jié)果按照哪個(gè)屬性排序姿鸿,以及排序順序谆吴。
- ?animal_type_id=1:指定篩選條件
參數(shù)的設(shè)計(jì)允許存在冗余,即允許 API 路徑和 URL 參數(shù)偶爾有重復(fù)苛预。比如句狼,GET /zoo/ID/animals 與 GET /animals?zoo_id=ID 的含義是相同的。
七热某、狀態(tài)碼
服務(wù)器向用戶返回的狀態(tài)碼和提示信息腻菇,常見的有以下一些(方括號(hào)中是該狀態(tài)碼對(duì)應(yīng)的 HTTP 動(dòng)詞)。
- 200 OK - [GET]:服務(wù)器成功返回用戶請(qǐng)求的數(shù)據(jù)昔馋,該操作是冪等的(Idempotent)筹吐。
- 201 CREATED - [POST/PUT/PATCH]:用戶新建或修改數(shù)據(jù)成功。
- 202 Accepted - [*]:表示一個(gè)請(qǐng)求已經(jīng)進(jìn)入后臺(tái)排隊(duì)(異步任務(wù))
- 204 NO CONTENT - [DELETE]:用戶刪除數(shù)據(jù)成功秘遏。
- 400 INVALID REQUEST - [POST/PUT/PATCH]:用戶發(fā)出的請(qǐng)求有錯(cuò)誤丘薛,服務(wù)器沒有進(jìn)行新建或修改數(shù)據(jù)的操作,該操作是冪等的邦危。
- 401 Unauthorized - [*]:表示用戶沒有權(quán)限(令牌洋侨、用戶名、密碼錯(cuò)誤)倦蚪。
- 403 Forbidden - [*] 表示用戶得到授權(quán)(與401錯(cuò)誤相對(duì))希坚,但是訪問是被禁止的。
- 404 NOT FOUND - [*]:用戶發(fā)出的請(qǐng)求針對(duì)的是不存在的記錄陵且,服務(wù)器沒有進(jìn)行操作裁僧,該操作是冪等的。
- 406 Not Acceptable - [GET]:用戶請(qǐng)求的格式不可得(比如用戶請(qǐng)求JSON格式慕购,但是只有XML格式)聊疲。
- 410 Gone -[GET]:用戶請(qǐng)求的資源被永久刪除,且不會(huì)再得到的沪悲。
- 422 Unprocesable entity - [POST/PUT/PATCH] 當(dāng)創(chuàng)建一個(gè)對(duì)象時(shí)售睹,發(fā)生一個(gè)驗(yàn)證錯(cuò)誤。
- 500 INTERNAL SERVER ERROR - [*]:服務(wù)器發(fā)生錯(cuò)誤可训,用戶將無法判斷發(fā)出的請(qǐng)求是否成功昌妹。
狀態(tài)碼的完全列表參見這里捶枢。
八、錯(cuò)誤處理
如果狀態(tài)碼是4xx飞崖,就應(yīng)該向用戶返回出錯(cuò)信息烂叔。一般來說,返回的信息中將 error 作為鍵名固歪,出錯(cuò)信息作為鍵值即可蒜鸡。
{
error: "Invalid API key"
}
九、返回結(jié)果
針對(duì)不同操作牢裳,服務(wù)器向用戶返回的結(jié)果應(yīng)該符合以下規(guī)范:
- GET /collection:返回資源對(duì)象的列表(數(shù)組)
- GET /collection/resource:返回單個(gè)資源對(duì)象
- POST /collection:返回新生成的資源對(duì)象
- PUT /collection/resource:返回完整的資源對(duì)象
- PATCH /collection/resource:返回完整的資源對(duì)象
- DELETE /collection/resource:返回一個(gè)空文檔
十逢防、Hypermedia API
RESTful API 最好做到 Hypermedia,即返回結(jié)果中提供鏈接蒲讯,連向其他 API 方法忘朝,使得用戶不查文檔,也知道下一步應(yīng)該做什么判帮。
比如局嘁,當(dāng)用戶向 api.example.com 的根目錄發(fā)出請(qǐng)求,會(huì)得到這樣一個(gè)文檔:
{"link": {
"rel": "collection https://www.example.com/zoos",
"href": "https://api.example.com/zoos",
"title": "List of zoos",
"type": "application/vnd.yourformat+json"
}}
上面代碼表示晦墙,文檔中有一個(gè) link
屬性悦昵,用戶讀取這個(gè)屬性就知道下一步該調(diào)用什么 API 了。rel
表示這個(gè) API 與當(dāng)前網(wǎng)址的關(guān)系(collection 關(guān)系晌畅,并給出該 collection 的網(wǎng)址)但指,href
表示 API 的路徑,title
表示 API 的標(biāo)題抗楔,type
表示返回類型棋凳。
Hypermedia API 的設(shè)計(jì)被稱為 HATEOAS。Github 的 API 就是這種設(shè)計(jì)谓谦,訪問 api.github.com 會(huì)得到一個(gè)所有可用 API 的網(wǎng)址列表。
{
"current_user_url": "https://api.github.com/user",
"authorizations_url": "https://api.github.com/authorizations",
// ...
}
從上面可以看到贪婉,如果想獲取當(dāng)前用戶的信息反粥,應(yīng)該去訪問 api.github.com/user,然后就得到了下面結(jié)果疲迂。
{
"message": "Requires authentication",
"documentation_url": "https://developer.github.com/v3"
}
上面代碼表示才顿,服務(wù)器給出了提示信息,以及文檔的網(wǎng)址尤蒿。
十一郑气、其他
(1)API的身份認(rèn)證應(yīng)該使用 OAuth 2.0 框架。
(2)服務(wù)器返回的數(shù)據(jù)格式腰池,應(yīng)該盡量使用 JSON尾组,避免使用 XML忙芒。
總結(jié)
歡迎留言討論,有錯(cuò)誤請(qǐng)指出讳侨,謝謝呵萨!
【聯(lián)系我(QQ:3500229193)或者加入社群,請(qǐng)戳這里跨跨!】
參考鏈接
- https://en.wikipedia.org/wiki/Representational_state_transfer
- http://www.ruanyifeng.com/blog/2014/05/restful_api.html
- https://blog.csdn.net/px01ih8/article/details/78674685
- https://blog.csdn.net/hjc1984117/article/details/77334616
更新日志
- 2018.06.13 第一次更新
- 2018.06.14 第二次更新