摘要:互聯(lián)網(wǎng)通信協(xié)議協(xié)議,是一個(gè)無(wú)狀態(tài)協(xié)議。具體來(lái)說(shuō),就是協(xié)議里面,四個(gè)表示操作方式的動(dòng)詞。版本號(hào)的版本號(hào)和客戶端的版本號(hào)是毫無(wú)關(guān)系的,不要讓將它們用于提交應(yīng)用市場(chǎng)的版本號(hào)傳遞到服務(wù)器,而是提供類似于之類的版本號(hào)。版本號(hào)拼接在中。
為什么要用 RESTful
RESTful 給我的最大感覺(jué)就是規(guī)范、易懂和優(yōu)雅,一個(gè)結(jié)構(gòu)清晰、易于理解的 API 完全可以省去許多無(wú)意義的溝通和文檔。并且 RESTful 現(xiàn)在越來(lái)越流行,
在開(kāi)始介紹 RESTful API 之前,先介紹一下 RESTful 架構(gòu)。
RESTful 架構(gòu)REST,即Representational State Transfer 的縮寫。意為 " 表現(xiàn)層狀態(tài)轉(zhuǎn)化 " 。
要理解RESTful架構(gòu),最好的方法就是去理解 Representational State Transfer 這個(gè)詞組到底是什么意思,它的每一個(gè)詞代表了什么涵義。如果把這個(gè)名稱搞懂了,也就不難體會(huì) REST 是一種什么樣的設(shè)計(jì)。
資源 (Resources)REST的名稱"表現(xiàn)層狀態(tài)轉(zhuǎn)化"中,省略了主語(yǔ)。"表現(xiàn)層"其實(shí)指的是"資源"(Resources)的"表現(xiàn)層"。
所謂"資源",就是網(wǎng)絡(luò)上的一個(gè)實(shí)體,或者說(shuō)是網(wǎng)絡(luò)上的一個(gè)具體信息。它可以是一段文本、一張圖片、一首歌曲、一種服務(wù),總之就是一個(gè)具體的實(shí)在。你可以用一個(gè) URI(統(tǒng)一資源定位符)指向它,每種資源對(duì)應(yīng)一個(gè)特定的 URI 。要獲取這個(gè)資源,訪問(wèn)它的 URI 就可以,因此 URI 就成了每一個(gè)資源的地址或獨(dú)一無(wú)二的識(shí)別符。所謂"上網(wǎng)",就是與互聯(lián)網(wǎng)上一系列的"資源"互動(dòng),調(diào)用它的 URI 。
表現(xiàn)層(Representation)"資源"是一種信息實(shí)體,它可以有多種外在表現(xiàn)形式。我們把"資源"具體呈現(xiàn)出來(lái)的形式,叫做它的"表現(xiàn)層"(Representation)。
比如,文本可以用 txt 格式表現(xiàn),也可以用 HTML 格式、 XML 格式、JSON 格式表現(xiàn),甚至可以采用二進(jìn)制格式;圖片可以用 JPG 格式表現(xiàn),也可以用 PNG 格式表現(xiàn)。
URI 只代表資源的實(shí)體,不代表它的形式。嚴(yán)格地說(shuō),有些網(wǎng)址最后的" .html "后綴名是不必要的,因?yàn)檫@個(gè)后綴名表示格式,屬于"表現(xiàn)層"范疇,而 URI 應(yīng)該只代表"資源"的位置。它的具體表現(xiàn)形式,應(yīng)該在 HTTP 請(qǐng)求的頭信息中用 Accept 和 Content-Type 字段指定,這兩個(gè)字段才是對(duì)"表現(xiàn)層"的描述。
訪問(wèn)一個(gè)網(wǎng)站,就代表了客戶端和服務(wù)器的一個(gè)互動(dòng)過(guò)程。在這個(gè)過(guò)程中,勢(shì)必涉及到數(shù)據(jù)和狀態(tài)的變化。
互聯(lián)網(wǎng)通信協(xié)議 HTTP 協(xié)議,是一個(gè)無(wú)狀態(tài)協(xié)議。這意味著,所有的狀態(tài)都保存在服務(wù)器端。因此,如果客戶端想要操作服務(wù)器,必須通過(guò)某種手段,讓服務(wù)器端發(fā)生"狀態(tài)轉(zhuǎn)化"(State Transfer)。而這種轉(zhuǎn)化是建立在表現(xiàn)層之上的,所以就是"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。
客戶端用到的手段,只能是HTTP協(xié)議。具體來(lái)說(shuō),就是HTTP協(xié)議里面,四個(gè)表示操作方式的動(dòng)詞:GET 、 POST 、 PUT 、 DELETE 。 它們分別對(duì)應(yīng)四種基本操作: GET 用來(lái)獲取資源, POST 用來(lái)新建資源,PUT 用來(lái)更新資源,DELETE 用來(lái)刪除資源。
總結(jié)一下什么是RESTful架構(gòu):
每一個(gè)URI代表一種資源;
客戶端和服務(wù)器之間,傳遞這種資源的某種表現(xiàn)層;
客戶端通過(guò)四個(gè)HTTP動(dòng)詞,對(duì)服務(wù)器端資源進(jìn)行操作,實(shí)現(xiàn)"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。
RESTful API 的設(shè)計(jì)介紹完 RESTful 的含義,再說(shuō)說(shuō) RESTful API 的設(shè)計(jì)。
協(xié)議如果能全站 HTTPS 當(dāng)然是最好的,不能的話也請(qǐng)盡量將登錄、注冊(cè)等涉及密碼的接口使用 HTTPS。
域名應(yīng)該盡量將API部署在專用域名之下。如:
https://api.example.com
如果確定API很簡(jiǎn)單,不會(huì)有進(jìn)一步擴(kuò)展,可以考慮放在主域名下。
https://example.org/api/版本號(hào)
API 的版本號(hào)和客戶端 APP 的版本號(hào)是毫無(wú)關(guān)系的,不要讓 APP 將它們用于提交應(yīng)用市場(chǎng)的版本號(hào)傳遞到服務(wù)器,而是提供類似于v1、v2之類的 API 版本號(hào)。
版本號(hào)拼接在 URL 中。如:
api.example.com/v1/users
或是放在 Header 中:
api.xxx.com/users version=v1請(qǐng)求
一般來(lái)說(shuō) API 的外在形式無(wú)非就是增刪改查(當(dāng)然具體的業(yè)務(wù)邏輯肯定要復(fù)雜得多),而查詢又分為詳情和列表兩種,在 RESTful 中這就相當(dāng)于通用的模板。例如針對(duì)文章(Article)設(shè)計(jì) API,那么最基礎(chǔ)的 URL 就是這幾種:
GET /articles: 文章列表
GET /articles/id:文章詳情
POST /articles/: 創(chuàng)建文章
PUT /articles/id:修改文章
DELETE /articles/id:刪除文章
Token 和 SignAPI 需要設(shè)計(jì)成無(wú)狀態(tài),所以客戶端在每次請(qǐng)求時(shí)都需要提供有效的 Token 和 Sign,在我看來(lái)它們的用途分別是:
Token 用于證明請(qǐng)求所屬的用戶,一般都是服務(wù)端在登錄后隨機(jī)生成一段字符串(UUID)和登錄用戶進(jìn)行綁定,再將其返回給客戶端。Token 的狀態(tài)保持一般有兩種方式實(shí)現(xiàn):一種是在用戶每次操作都會(huì)延長(zhǎng)或重置 TOKEN 的生存時(shí)間(類似于緩存的機(jī)制),另一種是 Token 的生存時(shí)間固定不變,但是同時(shí)返回一個(gè)刷新用的 Token,當(dāng) Token 過(guò)期時(shí)可以將其刷新而不是重新登錄。
Sign 用于證明該次請(qǐng)求合理,所以一般客戶端會(huì)把請(qǐng)求參數(shù)拼接后并加密作為 Sign 傳給服務(wù)端,這樣即使被抓包了,對(duì)方只修改參數(shù)而無(wú)法生成對(duì)應(yīng)的 Sign 也會(huì)被服務(wù)端識(shí)破。當(dāng)然也可以將時(shí)間戳、請(qǐng)求地址和 Token 也混入 Sign,這樣 Sign 也擁有了所屬人、時(shí)效性和目的地。
業(yè)務(wù)參數(shù)在 RESTful 的標(biāo)準(zhǔn)中,PUT 和 PATCH 都可以用于修改操作,它們的區(qū)別是 PUT 需要提交整個(gè)對(duì)象,而 PATCH 只需要提交修改的信息。但是在我看來(lái)實(shí)際應(yīng)用中不需要這么麻煩,所以我一律使用 PUT,并且只提交修改的信息。
另一個(gè)問(wèn)題是在 POST 創(chuàng)建對(duì)象時(shí),究竟該用表單提交更好些還是用 JSON 提交更好些。其實(shí)兩者都可以,在我看來(lái)它們唯一的區(qū)別是 JSON 可以比較方便的表示更為復(fù)雜的結(jié)構(gòu)(有嵌套對(duì)象)。另外無(wú)論使用哪種,請(qǐng)保持統(tǒng)一,不要兩者混用。
還有一個(gè)建議是最好將過(guò)濾、分頁(yè)和排序的相關(guān)信息全權(quán)交給客戶端,包括過(guò)濾條件、頁(yè)數(shù)或是游標(biāo)、每頁(yè)的數(shù)量、排序方式、升降序等,這樣可以使 API 更加靈活。但是對(duì)于過(guò)濾條件、排序方式等,不需要支持所有方式,只需要支持目前用得上的和以后可能會(huì)用上的方式即可,并通過(guò)字符串枚舉解析,這樣可見(jiàn)性要更好些。例如:
搜索,客戶端只提供關(guān)鍵詞,具體搜索的字段,和搜索方式(前綴、全文、精確)由服務(wù)端決定:
/users/?query=ScienJus
過(guò)濾,只需要對(duì)已有的情況進(jìn)行支持:
/users/?gender=1
分頁(yè):
/users/?page=2&pre_page=20響應(yīng)
盡量使用 HTTP 狀態(tài)碼,常用的有:
200:請(qǐng)求成功
201:創(chuàng)建、修改成功
204:刪除成功
400:參數(shù)錯(cuò)誤
401:未登錄
403:禁止訪問(wèn)
404:未找到
500:系統(tǒng)錯(cuò)誤
但是有些時(shí)候僅僅使用 HTTP 狀態(tài)碼沒(méi)有辦法明確的表達(dá)錯(cuò)誤信息,所以也可以在里面再包一層自定義的返回碼,例如:
成功時(shí):
{ "code": 100, "msg": "成功", "data": {} }
{ "code": -1000, "msg": "用戶名或密碼錯(cuò)誤" }
data是真正需要返回的數(shù)據(jù),并且只會(huì)在請(qǐng)求成功時(shí)才存在,msg只用在開(kāi)發(fā)環(huán)境,并且只為了開(kāi)發(fā)人員識(shí)別??蛻舳诉壿嬛辉试S識(shí)別code,并且不允許直接將msg的內(nèi)容展示給用戶。如果這個(gè)錯(cuò)誤很復(fù)雜,無(wú)法使用一段話描述清楚,也可以在添加一個(gè)doc字段,包含指向該錯(cuò)誤的文檔的鏈接。
返回?cái)?shù)據(jù)JSON 比 XML 可視化更好,也更加節(jié)約流量,所以盡量不要使用 XML。
創(chuàng)建和修改操作成功后,需要返回該資源的全部信息。
返回?cái)?shù)據(jù)不要和客戶端界面強(qiáng)耦合,不要在設(shè)計(jì) API 時(shí)就考慮少查詢一張關(guān)聯(lián)表或是少查詢 / 返回幾個(gè)字段能帶來(lái)多大的性能提升。并且一定要以資源為單位,即使客戶端一個(gè)頁(yè)面需要展示多個(gè)資源,也不要在一個(gè)接口中全部返回,而是讓客戶端分別請(qǐng)求多個(gè)接口。
最好將返回?cái)?shù)據(jù)進(jìn)行加密和壓縮,尤其是壓縮在移動(dòng)應(yīng)用中還是比較重要的。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/26204.html
摘要:其他交互一般會(huì)遵循一些數(shù)據(jù)結(jié)構(gòu)協(xié)議或者狀態(tài)值,比如不同的操作結(jié)果對(duì)應(yīng)不同的狀態(tài)值,且出錯(cuò)會(huì)返回指定的錯(cuò)誤信息方便前端進(jìn)行提示等。 RESTful這種架構(gòu)已經(jīng)具有很長(zhǎng)的時(shí)間和歷程了,但似乎最近restful這個(gè)詞出現(xiàn)的頻率特別高,目前不是很清楚是因?yàn)槲易詡€(gè)兒現(xiàn)在是以restful風(fēng)格寫程序產(chǎn)生的孕婦效應(yīng),還是單頁(yè)面程序開(kāi)發(fā)的流行造成的。 其實(shí)一開(kāi)始我也是不想寫這篇文章的,因?yàn)榫W(wǎng)絡(luò)上與re...
showImg(https://segmentfault.com/img/bV6aHV?w=1280&h=800); 社區(qū)優(yōu)秀文章 Laravel 5.5+passport 放棄 dingo 開(kāi)發(fā) API 實(shí)戰(zhàn),讓 API 開(kāi)發(fā)更省心 - 自造車輪。 API 文檔神器 Swagger 介紹及在 PHP 項(xiàng)目中使用 - API 文檔撰寫方案 推薦 Laravel API 項(xiàng)目必須使用的 8 個(gè)...
摘要:狀態(tài)碼狀態(tài)碼范圍信息,請(qǐng)求收到,繼續(xù)處理。范圍的狀態(tài)碼是保留給服務(wù)器端錯(cuò)誤用的。當(dāng)收到響應(yīng)時(shí),客戶端不可能知道服務(wù)器的狀態(tài),所以這類狀態(tài)碼是要盡可能的避免。服務(wù)器向用戶返回的狀態(tài)碼和提示信息,常見(jiàn)的有以下一些方括號(hào)中是該狀態(tài)碼對(duì)應(yīng)的動(dòng)詞。 這篇 文章主要是借鑒他人,但是自己很想總結(jié)出一套規(guī)范,以供向我這樣的新手使用,用來(lái)規(guī)范代碼,如果有什么好的提議,請(qǐng)不吝賜教,本篇文章長(zhǎng)期更新! 一、...
摘要:滿足這些約束條件和原則的應(yīng)用程序或設(shè)計(jì)就是。需要注意的是,是設(shè)計(jì)風(fēng)格而不是標(biāo)準(zhǔn)。同一個(gè)路徑,因?yàn)檎?qǐng)求方式的不同,而去找尋不同的接口,完成對(duì)資源狀態(tài)的轉(zhuǎn)變。一個(gè)符合風(fēng)格的就可以稱之一個(gè)的接口。 RESTful 相信在座的各位對(duì)于RESTful都是略有耳聞,那么RESTful到底是什么呢? REST(Representational State Transfer)表述性狀態(tài)轉(zhuǎn)移是一組架構(gòu)約...
摘要:則是目前比較成熟的一套互聯(lián)網(wǎng)應(yīng)用程序的設(shè)計(jì)理論。則允許操作,不一樣,報(bào)錯(cuò)返回或者加入黑名單。再看下我們的數(shù)據(jù)庫(kù)中的用戶信息,值也被存入了進(jìn)來(lái),便于我們之后進(jìn)行權(quán)限驗(yàn)證。訪問(wèn)同時(shí)將我們的值在中以傳入正確獲得用戶名則表示我們?cè)L問(wèn)請(qǐng)求通過(guò)了驗(yàn)證。 showImg(https://segmentfault.com/img/remote/1460000008629635?w=800&h=534)...
閱讀 1320·2021-11-23 09:51
閱讀 2063·2021-10-08 10:05
閱讀 2447·2019-08-30 15:56
閱讀 1970·2019-08-30 15:55
閱讀 2719·2019-08-30 15:55
閱讀 2565·2019-08-30 13:53
閱讀 3571·2019-08-30 12:52
閱讀 1444·2019-08-29 10:57