最近主導(dǎo)了公司的一次RESTful API的重新設(shè)計以及代碼重構(gòu),查閱了很多不同公司的做法,整理了一套相對完整的設(shè)計指導(dǎo),在這里分享給大家。文章主要分為兩部分,第一部分會介紹RESTful基本的設(shè)計指南,第二部分則會詳細介紹具體設(shè)計中碰到的問題。
RESTful沒有「準則」
REST的全稱——Representational state transfer,表現(xiàn)層狀態(tài)轉(zhuǎn)移是一種Web服務(wù)的設(shè)計思想,核心在于RESTful把Web實體抽象為資源,而對資源的種種操作,則都通過HTTP協(xié)議的動詞來表現(xiàn)。
「一切皆為資源」,可是如何去把一個實體轉(zhuǎn)化為資源,不同的API設(shè)計者會有不同的想法。RESTful并不是一種很強的約束,也不是一套萬能的框架,具體如何設(shè)計,還是要根據(jù)實際的業(yè)務(wù)需求、安全性、易用性等方面去考慮。
URL基本構(gòu)成

域名
如圖所示,URL的第一部分是域名加上“/api/”或直接將API融入域名中,來表明這是一個用于API的專屬鏈接。
模塊名
緊接著是一個模塊名,表示該API所在的具體的業(yè)務(wù)模塊,像谷歌就有youtube, drive等等。但如果你的API只對應(yīng)單一的業(yè)務(wù),這一部分是可以省略的。
Spotify的API只對音樂提供不同的接口,就省略了這一部分。
版本號
基本上大多數(shù)的API提供方都會把版本號放在URL內(nèi),通常發(fā)布后的REST服務(wù)不會在同一個版本內(nèi)做大的改動。
資源名
資源名的設(shè)計需要遵循一定的原則,這些原則會讓你的API看起來更加清晰、統(tǒng)一以及易用,但這并不是強制性的規(guī)范。
- 使用名詞
動詞都將被轉(zhuǎn)移至HTTP動詞,資源名詞和HTTP動詞的結(jié)合能更清晰地表現(xiàn)出API的操作 - 使用復(fù)數(shù)
不管這個資源是不是一個列表或組合,都用復(fù)數(shù)來表現(xiàn),可以減輕設(shè)計者的頭疼,也可以避免冗余的相近的API - 使用英文小寫
- 避免使用下劃線“_”,用橫線“-”代替
參數(shù)
當需要對URL返回的資源進行過濾或者篩選時,就需要用到參數(shù)。
常見的URL參數(shù)分兩種,一種是直接寫在URL內(nèi)的,也被成為URL變量,如下圖的1:
https://www.sampleapis.com/drive/v2/files/1
另一種是加在URL的最后,通常作為查詢參數(shù):
https://www.sampleapis.com/drive/v2/files?id=1
HTTP動詞
HTTP動詞可以表明對資源的增刪改查操作,它們的具體含義如下:
| 動詞 | 具體操作 | 返回消息體 |
|---|---|---|
| GET | 獲取資源 | 返回資源對象 |
| POST | 新增資源 | 返回新增的資源對象或資源的位置 |
| PUT | 完整地替換資源 | 返回修改后的資源對象或資源的位置 |
| PATCH | 更新資源的部分信息 | 返回修改后的資源對象或資源的位置 |
| DELETE | 刪除資源 | 無需返回消息體 |
HTTP狀態(tài)碼
HTTP狀態(tài)碼作為HTTP請求的返回的一部分,已經(jīng)能涵蓋非常多的狀態(tài)信息,這邊只列舉了一些常用的狀態(tài)碼:
| 狀態(tài)碼 | 具體信息 |
|---|---|
| 200 OK | 服務(wù)器返回成功,通常會附帶消息體 |
| 201 Created | 新建或修改服務(wù)器的成功 |
| 202 Accepted | 請求已被接服務(wù)器接收并開始處理,用于異步處理 |
| 400 Bad Request | 請求有錯誤,服務(wù)器未處理(4開頭的錯誤碼通常都是客戶端發(fā)出的請求有問題) |
| 404 Not Found | 未找到請求的資源 |
| 409 Confilct | 通常是對已經(jīng)存在的資源進行了重復(fù)創(chuàng)建,服務(wù)器認為是沖突 |
| 500 Internal Server Error | 服務(wù)器發(fā)生錯誤(5開頭的錯誤碼通常是服務(wù)器端發(fā)生異常) |
認證
RESTful API一般建議使用OAuth2.0的框架做身份認證,配合以JWT作為Token的格式。OAuth2.0保證了RESTful API的無狀態(tài)性。
REST API 設(shè)計技巧
其實在這次重構(gòu)中,因為碰到了許多不同的應(yīng)用場景,也分享一下一些設(shè)計API時的技巧。
URL變量還是參數(shù)?
上面有提到,取一個id為1的資源時,可以使用URL變量(resources/1)或是URL參數(shù)(resources?id=1)的方式。但是如果要取得id從1到5的資源,URL變量就會變得很奇怪了,這時候使用URL參數(shù)就更加合適。URL參數(shù)也可以用來做分頁、排序等功能。
非增刪改查的操作
HTTP動詞能夠表示對資源的增刪改查操作,可是如果是其他的操作呢?比如播放、喜歡歌曲,啟動、關(guān)閉系統(tǒng)...這時候HTTP動詞好像就無能為力了。傳統(tǒng)的API設(shè)計方法如下:
/songs/1/play
/songs/1/like
可這樣不是違反了URL中不能出現(xiàn)動詞的規(guī)則了嗎?但這確實是一種解決方法,而且許多大公司也這樣做,這樣的API其實足夠清晰易用,沒什么理由能夠讓人拒絕。
如果一定要遵守不出現(xiàn)動詞的規(guī)則,下面有一個方法,也可以試一下:
/songs/1?operation=play
/songs?id=1,2,3,4,5&operation=like
這個方法的還有一個好處在于,它可以同時對多個資源進行操作。無論選擇哪種形式,記得在你的API里保持一致性。
文檔
RESTful API絕對需要良好的文檔說明,文檔不僅可以幫助API使用者了解具體的數(shù)據(jù)格式以及資源請求方式,也可以幫助API開發(fā)者在版本演技和維護時,不斷審視需求等。
RESTful文檔通常需要包含具體的URL資源以及對應(yīng)的各種HTTP動詞的操作解釋、請求和返回的格式、示例請求等,比較成熟的文檔框架可以參考Swagger https://swagger.io/。