一,起源
-
REST全稱是Representational State Transfer ,中文意思是表述性狀態轉移。
-
於2000年首次被Roy Fielding的博士論文中出現,同時Roy Fielding也是HTTP
1.1規範的主要編寫人之一,(先有了該REST概念,後有了HTTP 1,1規範),該論文中明確指出REST指的是一組架構約束條件和原則( 很多人會誤以爲REST是一個新的技術,組件或服務,但其實全不是)。
那麼什麼是RESTful呢?
- 如果一個應用程序的架構符合REST的約束條件和原則,就稱之爲RESTful架構。
另外REST本身受Web技術的影響很深,但是理論上REST架構風格並非是綁定在HTTP上的,而是因爲目前HTTP是唯一與REST相關的實例,接下來要仔細講解的REST也是通過HTTP實現的REST。
二,REST詳解
REST的主要原則
- 一切皆資源
- 每個資源都具有唯一標識的資源標識符 URL
- 同一個資源具有多種表現形式,JSON,XML等 (通過Content-Type指定)
- 對各種資源的操作不會影響資源標識符
- 無狀態操作
其中主要有如下約束和規範
-
客戶端發送的數據指令都是“動詞”+“賓語”的結構
例如
GET /users
POST /users
動詞—請求方式,主要有如下幾種,可以大致的與對數據的常見操作CRUD對應。
GET :冪等 Read
POST:不冪等 Create
PUT :冪等 更新(Update)
PATCH:冪等 部分更新(Update)
DELETE :冪等 刪除 (Delete)
注:請求方式一律大寫 -
賓語規範
以上說完了動詞,接下來就說說“賓語”,
規範:賓語只能是名詞
例如:獲取學生信息
/getUser 不符合規範
/users 規範,
上面之所以採用複數,是因爲獲取的是一個數據集 -
減少資源層級關係
在獲取某一資源時,儘量使用查詢字符串來替代多層級
例如:獲取武漢市洪山區的高級中學
/city/2/area/3/schoolType/high
建議規範:
/city/2?area=3&schoolType=highschool
查詢已完成工作:
/work/complete
建議規範:
/work?complete=true
這樣寫的好處,利於擴展,接口語義表達明確,通俗易懂 -
狀態碼
每當我們發送HTTP請求,都會獲取到狀態碼+數據體。
常見狀態碼:
2XX 操作成功
3XX 重定向
4XX 客戶端錯誤
5XX 服務器錯誤
一種逐漸向外擴散的傾向。 -
無狀態&狀態轉移
實際上,所謂的狀態應該區分爲應用狀態和資源狀態,客戶端應用負責維護應用狀態,服務端負責維護資源狀態。而客戶端與服務端的交互必須是無狀態的。
例:
基於狀態的Web服務,客戶端與服務器交互的信息會保存在服務器的Session中,在這種前提下。客戶端的請求就只能被保存有關用戶相關狀態信息的服務器所受理,這也就意味着,在基於狀態的Web系統中服務器無法對用戶請求進行負載均衡等操作(一個服務器只能處理特定的客戶端請求)
在無狀態的Web服務中,每一個Web請求都是獨立的,請求之間完全分離,服務器不保存客戶端的狀態信息,每一個請求可以被任何一個可用的服務器受理,從而可以實現負載均衡等分佈式系統特性
說到這裏就再總結一下:
無狀態請求:Server不保存任何請求狀態信息,Client的每一個請求都具有可被執行等所需要的全部信息,所以能被任意可用的Server應答。
有狀態請求:Server保存了Client的請求狀態,Server會通過Client傳遞的SessionID在Server中的Session作用域找到之前交互的信息,並以此來實現應答。所以Client只能由某一個Server來應答。
此處關於無狀態的解釋,多參照於此篇
以上也就可以很好解釋:
表述性狀態轉移中所謂的狀態轉移
特例:有些客戶端比較老,只能支持GET和POST兩種方法,
這時,我們可以給請求中加一個屬性:
X-HTTP-Method-Overried
使用POST方式發送PUT請求:
加屬性:
X-HTTP-Method-Overried:PUT即可指定此次請求是PUT請求,而非POST請求
三,SpringBoot中的RESTful實現
在SpringBoot中使用@RequestMapping註解的method屬性實現了該規範:
//常見的請求方式
RequestMapping(method=RequestMethod.GET)
RequestMapping(method=RequestMethod.POST)
RequestMapping(method=RequestMethod.DELETE)
RequestMapping(method=RequestMethod.PUT)
//SpringBoot支持的請求方式,看源碼
public enum RequestMethod {
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
}