REST(Representational State Transfer, 表述性狀態(tài)轉移),源于Roy Thomas Fielding博士在2000年在校期間發(fā)表的一篇學術論文《Architectural Styles and the Design of Network-based Software Architectures》驳庭。從題目中也可以看出來REST是一種架構風格,不是一種協(xié)議或者技術。
RESTful API 翻譯過來就是REST式的API就是滿足REST這種風格的API户辞。具有跨平臺疟羹、跨語言的優(yōu)勢碳柱,并且實現(xiàn)簡潔直觀构哺。近來越來越受開發(fā)者喜歡革答,特別是最近微服務化的火熱又推動了一把REST的使用。
特點
論文中提出了REST的6個特點:
- 客戶端-服務器的
- 無狀態(tài)的
- 可緩存的
- 統(tǒng)一接口
- 分層系統(tǒng)
- 按需編碼
這6個特點具體所指可以看下論文原文曙强,或者可以看下這個連接蝗碎。
REST實現(xiàn)方式
基于即有的HTTP/HTTPS + URI + XML/JSON
實現(xiàn)。在REST架構風格中旗扑,對象被抽象成一種資源(使用清晰的名詞來定義)。
REST的資源是通過HTTP協(xié)議定義的動詞(GET/PUT/POST/DELETE等)來操作慈省,并使用URI來唯一標識某個資源公布出來的接口臀防。
每種HTTP請求方法都可以從安全性和冪等性兩方面來考慮:安全性是指外系統(tǒng)對該接口的訪問不會使得服務器端的資源的狀態(tài)發(fā)生改變;冪等性是指外系統(tǒng)對同一REST接口的多次訪問得到的資源狀態(tài)是相同的边败。
- GET/HEAD/OPTIONS三個方法即是安全的又是冪等的
- PUT/DELETE方法是冪等的袱衷,但是不安全的,因為PUT是一種寫操作
- POST既不冪等也不安全
PUT和POST是爭議性最大的兩個方法笑窜,作用比較接近致燥,一般來說使用PUT來更新數(shù)據(jù),而使用POST來添加數(shù)據(jù)
當然這只是REST中對這些HTTP方法賦予的規(guī)范性排截,并沒有要求用戶必須這樣實現(xiàn)嫌蚤,但如果按照這種規(guī)范性來實現(xiàn)會使用接口變得更通用辐益,更易于理解維護。
REST資源定位
REST使用URI實現(xiàn)資源定位脱吱,即對外提供的接口就是一系列的URI及其參數(shù)智政。
在設計RESTful API時資源地址的設計一定要非常嚴謹,如果設計不好不僅REST接口的風格無法統(tǒng)一箱蝠,系統(tǒng)的擴展性和易用性也會大打折扣续捂。
好的RESTful API中,資源名稱應是準確描述該資源的名詞宦搬,資源地址應該具有直觀的描述性牙瓢。例如小區(qū)/樓號/樓層/房屋號。
注意:在復雜的現(xiàn)實情況中是有很多情況是路徑變量難以準備描述的间校,可以考慮使用動詞做為查詢參數(shù)來解決矾克。
資源地址
一個典型的URI包括協(xié)議名稱、主機名撇簿、服務端口聂渊、資源地址和查詢字符串5部分組成。
schema://host:port/path?queryString
組成 | 說明 |
---|---|
schema | 協(xié)議名稱四瘫。一般是HTTP/HTTPS |
host | 主機名汉嗽,可以是域名或者ip |
port | 端口號 |
path | 資源地址, 使用/ 分隔邏輯上的層次結構 |
? | 分隔資源地址和查詢字符串找蜜,如果沒有查詢字符串饼暑,? 可省略 |
queryString | 查詢字符串洗做,key=value 形式弓叛,如果有多個可以使用& 連接 |
其中path
就是資源地址,一般使用basepath
和pathinfo
來細分诚纸;例如很有名的OpenAPI規(guī)范swagger撰筷。另外在web服務中basepath又被細分為contextpath
和servletpath
。
注意:資源地址是需要與HTTP方法結合一起來定位具體資源畦徘。資源地址相同HTTP方法不同兩個方法是對應兩個不同的REST接口的毕籽。例如
GET /books/<id>
和PUT /books/<id>
常用于資源URI中的標點符號
為了增加邏輯的清晰性,在路徑變量中提供了幾個常用的標點符號:
-
?
(問號):用來分隔資源地址和查詢字符串井辆,這個上一節(jié)有說明关筒。 -
&
(與):用來分隔多個查詢條件的參數(shù),這個上一節(jié)有說明杯缺。 -
,
(逗號):用來分隔邏輯上有次序的作用域信息蒸播,使用"月,日,年" -
-
(連接符):可以做為邏輯上的輔助分隔,例如2012-2018
表示2012年到2018年萍肆。 -
_
(下劃線):一般用于多個單詞的連接成一個完整的字段袍榆,例如book_type_id=1
-
;
(分號):用來分隔無次序的作用域信息胀屿,例如并列查詢條件。
常用的資源地址示例:
功能 | 資源地址 |
---|---|
添加/創(chuàng)建 | POST /books |
PUT /books/{id} |
|
刪除 | DELETE /books/{id} |
修改/更新 | PUT /books/{id} |
查詢全部 | GET /books |
主鍵查詢 | GET /books/{id} |
GET /books?id=12345 |
|
分頁作用域查詢 | GET /books?start=0&size=10 |
GET /books/01,2012-12,2014 |
|
GET /books/restful;program=java;type=web |
|
GET /books?limit=100&sort=bookname |
API接口版本
任何人設計的有用的功能都是要向前演進的蜡塌,不可能一成不變碉纳。一般是引入版本號的概念來解決這種演進的問題。而RESTful API的版本號可以通過以下幾種方式實現(xiàn):
- 在uri中放版本信息:GET /v1/users/1
- Accept Header:Accept: application/json+v1
- 自定義 Header:X-Api-Version: 1
通常建議使用第一種方式馏艾,簡單直觀劳曹。
其他
- RESTful API最好做到Hypermedia,即返回結果中提供鏈接琅摩,連向其他API方法铁孵,使得用戶不查文檔,也知道下一步應該做什么
- 請求以及返回數(shù)據(jù)使用JSON格式房资,不要使用XML格式
- 返回出錯信息時蜕劝,數(shù)據(jù)key統(tǒng)一起來,使用使用
ERROR
轰异,而錯誤信息作為value