1. 程式人生 > >Restful架構風格

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)- 服務端當前無法處理請求