Restful架構風格
REST是英文representational state transfer(表象性狀態轉移),Rest是web服務的一種架構風格;使用HTTP,URI,XML,JSON等廣泛流行的標準和協議;輕量級、跨平臺、跨語言的架構設計;它是一種設計風格,不是一個標準,是一種思想。Rest式的web服務是一種ROA(The Resource-Oriented Architecture)(面向資源的架構)
Rest架構的主要原則
網路上的所有事物都被抽象為資源
每個資源都有一個唯一的資源描述符(URI)
同一個資源具有多種表現形式(XML、JSON等)
對資源的各種操作不會改變資源描述符
所有的操作是無狀態的
符合REST原則的架構方式即可被稱為RESTful。
為什麼會出現Restful
在Restful之前的操作:
http://127.0.0.1/user/query/1 GET 根據使用者id查詢使用者資料
http://127.0.0.1/user/save POST 新增使用者
http://127.0.0.1/user/update POST 修改使用者資訊
http://127.0.0.1/user/delete GET/POST 刪除使用者資訊
RESTful用法:
http://127.0.0.1/user/1 GET 根據使用者id查詢使用者資料
http://127.0.0.1/user POST 新增使用者
http://127.0.0.1/user PUT 修改使用者資訊
http://127.0.0.1/user DELETE 刪除使用者資訊
我們可以看到使用Restful之前每次請求的介面或者地址,都在做描述,如查詢的時候用了query,新增的時候用了save,其實完全沒有這個必要,我使用了get請求,就是查詢,使用了post請求,就是新增的請求,我的意圖很明顯了,完全沒有必要做描述,這就是為什麼有了restful。
/* 根據id查詢使用者 */ @RequestMapping(value = "/{id}", method = RequestMethod.GET) public @ResponseBody User list(@PathVariable("id") String id){ Integer sid = Integer.valueOf(id); System.out.println(sid); User list = userService.findUserById(sid); return list; } /* 根據id刪除使用者 */ @RequestMapping(value="/{id}",method = RequestMethod.DELETE) public @ResponseBody String deleteUserById(@PathVariable("id") Integer id,@RequestParam(value = "name",required = true) String name){ userService.deleteUserById(id); return "刪除了"; }
用POST還是PUT
POST
用於提交請求,可以更新或者建立資源,是非冪等的
舉個例子,在我們的支付系統中,一個api的功能是建立收款金額二維碼,它和金額相關,每個使用者可以有多個二維碼,如果連續呼叫則會建立新的二維碼,這個時候就用POST
PUT
用於向指定的URI傳送更新資源,是冪等的
還是那個例子,使用者的賬戶二維碼只和使用者關聯,而且是一一對應的關係,此時這個api就可以用PUT,因為每次呼叫它,都將重新整理使用者賬戶二維碼
比如一個介面用於使用者生成,接收的資料是使用者名稱、密碼等相關資訊,則用POST
RESTful建議所有的URI都是對應資源,所以建立使用者不應該理解為一個行為,在此將此介面命名為:
/user/creation
每次呼叫它都會新建一個使用者(假定使用者名稱可以重複)
而PUT方法更加關心一個具體資源對應的URI,比如更新當前使用者資訊,這裡可以用PUT
/user/me/update
這裡用me來指代當前使用者,如果是針對更多使用者適用的介面,可以考慮
/user/{uid}/update
注意多次呼叫同一介面,只要提交的資料一致,使用者資訊每次結果就會一致,即產生同樣的結果:伺服器端某個具體的資源得到了更新
當需要以更新的形式來修改某一具體資源的時候,如何判斷用PUT還是POST呢?
很簡單,如果該更新對應的URI多次呼叫的結果一致,則PUT
比如更新某個blog文章,因為該文章具有單一的具體URI,所以每次更新提交相同的內容,結果都一致
/blog/{document_id}/update
在每次更新提交相同的內容,最終的結果不一致的時候,用POST
舉個很常見的例子,一個介面的功能是將當前餘額減一個值,每次提交指定該值為100,介面如下
/amount/deduction
呼叫一次,你的餘額-100,呼叫兩次,餘額-200
這個時候就用POST
GET
- 安全且冪等
- 獲取表示
- 變更時獲取表示(快取)
- 200(OK) - 表示已在響應中發出
- 204(無內容) - 資源有空表示
- 301(Moved Permanently) - 資源的URI已被更新
- 303(See Other) - 其他(如,負載均衡)
- 304(not modified)- 資源未更改(快取)
- 400 (bad request)- 指代壞請求(如,引數錯誤)
- 404 (not found)- 資源不存在
- 406 (not acceptable)- 服務端不支援所需表示
- 500 (internal server error)- 通用錯誤響應
- 503 (Service Unavailable)- 服務端當前無法處理請求
POST
- 不安全且不冪等
- 使用服務端管理的(自動產生)的例項號建立資源
- 建立子資源
- 部分更新資源
- 如果沒有被修改,則不過更新資源(樂觀鎖)
- 200(OK)- 如果現有資源已被更改
- 201(created)- 如果新資源被建立
- 202(accepted)- 已接受處理請求但尚未完成(非同步處理)
- 301(Moved Permanently)- 資源的URI被更新
- 303(See Other)- 其他(如,負載均衡)
- 400(bad request)- 指代壞請求
- 404 (not found)- 資源不存在
- 406 (not acceptable)- 服務端不支援所需表示
- 409 (conflict)- 通用衝突
- 412 (Precondition Failed)- 前置條件失敗(如執行條件更新時的衝突)
- 415 (unsupported media type)- 接受到的表示不受支援
- 500 (internal server error)- 通用錯誤響應
- 503 (Service Unavailable)- 服務當前無法處理請求
PUT
- 不安全但冪等
- 用客戶端管理的例項號建立一個資源
- 通過替換的方式更新資源
- 如果未被修改,則更新資源(樂觀鎖)
- 200 (OK)- 如果已存在資源被更改
- 201 (created)- 如果新資源被建立
- 301(Moved Permanently)- 資源的URI已更改
- 303 (See Other)- 其他(如,負載均衡)
- 400 (bad request)- 指代壞請求
- 404 (not found)- 資源不存在
- 406 (not acceptable)- 服務端不支援所需表示
- 409 (conflict)- 通用衝突
- 412 (Precondition Failed)- 前置條件失敗(如執行條件更新時的衝突)
- 415 (unsupported media type)- 接受到的表示不受支援
- 500 (internal server error)- 通用錯誤響應
- 503 (Service Unavailable)- 服務當前無法處理請求
DELETE
- 不安全但冪等
- 刪除資源
- 200 (OK)- 資源已被刪除
- 301 (Moved Permanently)- 資源的URI已更改
- 303 (See Other)- 其他,如負載均衡
- 400 (bad request)- 指代壞請求
- 404 (not found)- 資源不存在
- 409 (conflict)- 通用衝突
- 500 (internal server error)- 通用錯誤響應
- 503 (Service Unavailable)- 服務端當前無法處理請求