一、概述:
RESTful架構(gòu),就是目前最流行的一種互聯(lián)網(wǎng)軟件架構(gòu)。REST是Representational State Transfer詞組的簡寫,即“表現(xiàn)層狀態(tài)轉(zhuǎn)化”。代表(互聯(lián)網(wǎng)資源)表現(xiàn)層狀態(tài)轉(zhuǎn)化。
REST是Roy Fielding博士在2000年在其論文中第一個提到的,因為他是互聯(lián)網(wǎng)行業(yè)內(nèi)一個重要的人物(HTTP 1.0/1.1協(xié)議的主要設(shè)計者、Apache開源基金會的第一任主席),所以引起了人們的關(guān)注,并且對互聯(lián)網(wǎng)產(chǎn)生了深遠(yuǎn)的影響。
RESTful不是一個標(biāo)準(zhǔn),但是一種規(guī)范?,F(xiàn)在很多軟件使用使用前后端分離的應(yīng)用結(jié)構(gòu),它結(jié)構(gòu)清晰、符合標(biāo)準(zhǔn)、易于理解、擴(kuò)展方便。前端(H5、Android、iPhone、小程序)往往通過調(diào)用API的方式與后端進(jìn)行數(shù)據(jù)交換。那么,符合RESTful規(guī)范的軟件架構(gòu)的API我們可稱之為RESTful APl。如微博開放API和Github開放API就嚴(yán)格遵循了RESTful規(guī)范。
以上是對RESTful架構(gòu)的概述,在本文中,我將使用自己的理解完整的表述RESTful的規(guī)范,以及如何設(shè)計符合RESTful規(guī)范的API。實際上,在對計算機(jī)技術(shù)的理解中,一百個人可能會有一百種理解方式,盡管見仁見智,但我們的目的都是把技術(shù)當(dāng)作工具,去實現(xiàn)我們的程序功能。如果在本文中的描述有所錯誤,或您有所不解,歡迎留言評論!
下面將分為將分為三個內(nèi)容,展開描述我對RESTful的理解:
1.理解 RESTful
2.RESTful API架構(gòu)規(guī)范
3.RESTful API 設(shè)計示例
二、理解RESTful
要理解RESTful,我們需要從每一個詞開始理解。Roy Fielding將他對互聯(lián)網(wǎng)軟件的架構(gòu)原則命名為REST,即Representational State Transfer的縮寫,代表(資源)表現(xiàn)層狀態(tài)轉(zhuǎn)化。如果一個軟件架構(gòu)符合REST原則,就稱它為RESTful架構(gòu)。
1. 資源(Resources)
我們在互聯(lián)網(wǎng)軟件開發(fā)中,我們所說的“資源”是指在互聯(lián)網(wǎng)中某一個節(jié)點的具體信息,如一段文本、一張圖片、一個視頻、一個壓縮包、一個程序安裝包等等。在互聯(lián)網(wǎng)中,我們可以使用URI(統(tǒng)一資源定位符)來表示每一個具體的資源,因此,每一個互聯(lián)網(wǎng)資源都一個獨(dú)一無二的URI地址。
2. 表現(xiàn)層(Representational)
“資源”是一種信息的實體,實際上,資源有很多表現(xiàn)形成,如一段文本,我們可以使用普通的txt格式來表示,也可以用JSON格式來表示,還可以使用XML格式來表示?!百Y源”的具體表現(xiàn)形式我們就叫做表現(xiàn)層。在HTTP協(xié)議中,規(guī)定了頭信息中的Content-Type字段來描述具體的資源表現(xiàn)形式。如“Content-Type: text/html”表示為html格式的文本數(shù)據(jù),而“Content-Type: text/json”表示為JSON格式的文本數(shù)據(jù)。
1. 狀態(tài)轉(zhuǎn)化(State Transfer)
HTTP是一種無狀態(tài)的網(wǎng)絡(luò)協(xié)議,如果客戶端要操作服務(wù)器,必須通過一種手段通知服務(wù)器進(jìn)行“狀態(tài)轉(zhuǎn)化”,而這種狀態(tài)改變建立在“表現(xiàn)層”之上,這就是“表現(xiàn)層狀態(tài)轉(zhuǎn)化”。在HTTP協(xié)議中,客戶端通過發(fā)送相應(yīng)的請求告知服務(wù)器實現(xiàn)某種狀態(tài)的改變??蛻舳耸褂肎ET、POST、PUT、DELETE4個表示操作方式的動詞對服務(wù)端資源進(jìn)行操作。
綜上所述,我們可以總結(jié)一下RESTful的特點:
a. 每個互聯(lián)網(wǎng)資源都有一個唯一的URI地址;
b. 通過操作資源的表現(xiàn)形式來操作資源;
c. 一般情況下使用JSON格式來表示具體的數(shù)據(jù);
c. 使用HTTP協(xié)議進(jìn)行客戶端與服務(wù)端之間的交互,從客戶端到服務(wù)端的每個請求都必須包含理解請求所必需的信息;
d. 客戶端使用GET、POST、PUT、DELETE 4個表示操作方式的動詞對服務(wù)端資源進(jìn)行“狀態(tài)”操作。
三、RESTful API架構(gòu)規(guī)范
REST并沒有明確的設(shè)計標(biāo)準(zhǔn),可以說RESTful是一種設(shè)計風(fēng)格的規(guī)范化。在RESTful API設(shè)計中,不同的組織可能還存在不同的設(shè)計風(fēng)格規(guī)范,但是整體上RESTful的風(fēng)格規(guī)范是一致的。
也正是因為有了一致的風(fēng)格規(guī)范,讓讀API的人更好地理解API,甚至不用閱讀文檔,就知道API要實現(xiàn)的某個資源的某種“狀態(tài)轉(zhuǎn)化”。根據(jù)Github開放API或者微博開放API的設(shè)計風(fēng)格。下面是我總結(jié)的RESTful API的相關(guān)風(fēng)格規(guī)范,今后我將使用此規(guī)范進(jìn)行API開發(fā)。
1. 協(xié)議
客戶端與服務(wù)器之間使用HTTP或者HTTPS協(xié)議進(jìn)行通信。
2.域名
應(yīng)當(dāng)盡量將API程序部署到專有的域名之下,如:
https://api.demo.com
如果API比較簡單,或者不考慮進(jìn)行擴(kuò)展,應(yīng)當(dāng)放在項目的子模塊中,如:
https://demo.com/api/
3.API版本
應(yīng)當(dāng)將API版本放在URL中,如微博開放API就將版本號放在URL中:
http://api.weibo.com/2/
如果我們把版本號理解成資源的不同表述形式的話,API版本應(yīng)放在HTTP請求頭Accept字段中,如github中的開放API
Accept: application/vnd.github.v3
可能github考慮很多因素,所以把請求的API版本放到HTTP請求頭里了。實際上,如果我們想要快速的開發(fā)一個API程序,使用第一種形式會更加直觀與方便。
4.路徑
對于不同的資源,都有一個唯一的URL地址,每一個URL地址代表一種資源,所以網(wǎng)址中應(yīng)當(dāng)是名稱,不能是動詞,而且名詞應(yīng)當(dāng)與數(shù)據(jù)庫表名對應(yīng)。一般來說,數(shù)據(jù)庫中保存的是數(shù)據(jù)集合,所以URL中對應(yīng)的資源應(yīng)當(dāng)是名詞復(fù)數(shù)。
如Github開放API中,列出一個組織的項目集合:
https://api.github.com/orgs/:org/projects
在上面URL中,orgs代表組織集合,而:org代表集體的組織名,projects代表具體的資源
5.HTTP動詞
對于資源的某種具體操作類型,需要客戶端發(fā)送不同的HTTP動作來完成。
常用的五個HTTP動詞已經(jīng)對應(yīng)操作如下:
* GET(Retrieve):從服務(wù)器取出資源(一項或多項);
* POST(CREATE):在服務(wù)器新建一個資源;
* PUT(UPDATE):在服務(wù)器更新資源(客戶端提供改變后的完整資源);
* PATCH(UPDATE):在服務(wù)器更新資源(客戶端提供改變的屬性);
* DELETE(DELETE):從服務(wù)器刪除資源。
實際上,最常用的額HTTP動詞原先只有4個,即GET、POST、PUT、DELETE,PATCH方法是新引入的,是對PUT方法的補(bǔ)充,用來對已知資源進(jìn)行局部更新。
有時候,只需要修改一個屬性,開發(fā)者通常(為圖省事)把一個包含了修改后完整信息傳給后端,做完整更新。但實際上如果需要考慮性能優(yōu)化,是有必要做局部更新的。
6.過濾
在獲取服務(wù)器資源的時候,大部分情況是需要進(jìn)行過濾的,而不是獲取數(shù)據(jù)庫中的完整集合。這時候需要設(shè)置過濾條件,我們可以將過濾條件作為參數(shù)拼接到URL中。如下:
?limit=10 # 指定獲取10條信息集合
?page=1&limit=10 # 指定每頁10條信息,獲取第1頁信息集合
?limit=10&deleted=true # 獲取數(shù)據(jù)庫中已經(jīng)標(biāo)志為刪除的10條信息集合
7.返回
使用相應(yīng)的HTTP狀態(tài)碼,將結(jié)果告知客戶端,以下是常用的HTTP狀態(tài)碼以及狀態(tài)描述:
| 狀態(tài)碼 | 描述 | 備注 |
|---|---|---|
| 200 | OK - 成功 | |
| 204 | NO CONTENT - 無內(nèi)容 | DELETE返回204狀態(tài)碼,表示資源已經(jīng)不存在 |
| 303 | See Other - 其他 | 表示參考另一個 URL,此時應(yīng)當(dāng)返回URL鏈接 |
| 400 | bad request - 服務(wù)器不理解客戶端的請求(如,參數(shù)錯誤) | |
| 401 | Unauthorized - 沒有通過身份驗證 | |
| 403 | Forbidden - 沒有訪問權(quán)限 | |
| 404 | Not Found - 資源不存在,或不可用 | |
| 405 | Method Not Allowed - 對于此HTTP方法沒有權(quán)限 | |
| 409 | conflict - 通用沖突 | 如被請求的資源與其當(dāng)前狀態(tài)之間存在沖突,請求無法完成 |
| 410 | Gone - 資源不存在,或不可用 | |
| 415 | unsupported media type - 不支持的媒體類型 | 如服務(wù)器需要客戶端使用JSON數(shù)據(jù)請求,而客戶端使用XML進(jìn)行請求 |
| 429 | Too Many Requests - 請求次數(shù)超過限額 | |
| 500 | internal server error - 服務(wù)器通用錯誤 | 如果客戶端請求有效,服務(wù)器處理時發(fā)生了意外 |
| 503 | Service Unavailable - 服務(wù)端當(dāng)前無法處理請求 | 如網(wǎng)站正在維護(hù),服務(wù)器無法處理請求 |
- 正常:如果正常返回數(shù)據(jù),應(yīng)當(dāng)使用msg或者其他關(guān)鍵字作為鍵名返回給客戶端,如下:
{
"data":[
"user_id":1,
"name":"張三",
"token":"csdcnsdvndsijudsao",
],
"message":"OK",
"code":200
}
- 錯誤:如果發(fā)生錯誤,應(yīng)當(dāng)使用error作為錯誤信息的鍵名返回給客戶端
{
"error":"Unauthorized",
"code":401
}
針對不同操作,服務(wù)器向用戶返回的結(jié)果應(yīng)該符合以下規(guī)范:
GET /collection:返回資源對象的列表(數(shù)組)
GET /collection/resource:返回單個資源對象
POST /collection:返回新生成的資源對象
PUT /collection/resource:返回完整的資源對象
PATCH /collection/resource:返回完整的資源對象
DELETE /collection/resource:返回一個空文檔
8.Hypermedia API
RESTful API最好做到Hypermedia,即超媒體,在返回結(jié)果中提供鏈接,連向其他API方法或者一些文檔,使得用戶不查文檔,也知道下一步應(yīng)該做什么。如Github就做到了Hypermedia,使用GET方式請求 https://api.github.com ,會返回一系列的鏈接地點:
{
"current_user_url": "https://api.github.com/user",
"current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}",
"authorizations_url": "https://api.github.com/authorizations",
"code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}",
"commit_search_url": "https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}",
.....
四、RESTful API設(shè)計示例
RESTful API風(fēng)格主要體現(xiàn)在URL中,接下來,我們通過一個示例,來完成RESful API的URL制定。假設(shè)我們要開發(fā)一個簡單的博客系統(tǒng),要給H5、Android、iPhone、小程序提供一套統(tǒng)一的接口。那么預(yù)設(shè)功能與對應(yīng)URL已經(jīng)請求方式如下:
| 模塊 | 功能 | URL | HTTP請求方式 |
|---|---|---|---|
| 用戶 | 用戶注冊 | http://api.demo.com/1.0/users/register | POST |
| 用戶 | 用戶登錄 | http://api.demo.com/1.0/users/login | POST |
| 文章 | 發(fā)表文章 | http://api.demo.com/1.0/articles | POST |
| 文章 | 查看文章 | http://api.demo.com/1.0/articles/:id | GET |
| 文章 | 修改文章 | http://api.demo.com/1.0/articles/:id | PUT |
| 文章 | 刪除文章 | http://api.demo.com/1.0/aritcles/:id | DELETE |
到此結(jié)束。
本文為作者原創(chuàng)文章,禁止轉(zhuǎn)載,原作者:https://phy.xyz