通俗易懂的RESTful API實踐詳解(含代碼)


來源:點擊進入

點擊上方鏈接,版面更好

 

一、什么是RESTful

        REST 是面向資源的,這個概念非常重要,而資源是通過 URI 進行暴露,URI 的設計只要負責把資源通過合理方式暴露出來就可以了,對資源的操作與它無關,操作是通過 HTTP動詞來體現。所以REST 通過 URI 暴露資源時,會強調不要在 URI 中出現動詞,而是對一類資源只提供一個url,通過GET、POST、PUT、DELETE請求來指定要執行的操作。

       非RESTful 用法(多個url且url中存在動詞)

    http://127.0.0.1/order/query/1 GET  根據訂單id查詢訂單數據
    http://127.0.0.1/order/save POST 新增訂單
    http://127.0.0.1/order/update POST 修改訂單信息
    http://127.0.0.1/order/delete GET/POST 刪除訂單信息

       RESTful 用法(同一個url,具體的操作通過HTTP請求方式來指定)

    http://127.0.0.1/order/1 GET  根據訂單id查詢訂單數據
    http://127.0.0.1/order  POST 新增訂單
    http://127.0.0.1/order  PUT 修改訂單信息
    http://127.0.0.1/order  DELETE 刪除訂單信息

        REST很好地利用了HTTP本身就有的一些特征,如HTTP動詞、HTTP狀態碼、HTTP報頭等等。
        REST API 是基於 HTTP的,所以你的API應該去使用 HTTP的一些標准。這樣所有的HTTP客戶端(如瀏覽器)才能夠直接理解你的API。

        REST返回值是標准的,我們不用單獨定義和封裝返回的狀態碼,而是直接使用HTTP的狀態碼,非RESTful 返回舉例:

    {
      "code": "0",
      "msg": "成功"
    }

    {
      "code": "1",
      "msg": "失敗"
    }

        這種方式還要我們自己去解析,還要前端和后端去協商你返回的0是啥意思。
二、RESTful 的關鍵

        RESTful的關鍵是定義可表示流程元素/資源的對象。在REST中,每一個對象都是通過URL來表示的,對象用戶負責將狀態信息打包進每一條消息內,以便對象的處理總是無狀態的。前后端分離的項目基本上就是無狀態的,我們經常通過簽名判斷當前的請求是否合法。

        所謂無狀態的,即所有的資源,都可以通過URI定位,而且這個定位與其他資源無關,也不會因為其他資源的變化而改變。

        舉個簡單的例子說明一下有狀態和無狀態的區別,如查詢員工的工資,如果查詢工資是需要登錄系統,進入查詢工資的頁面,執行相關操作后,獲取工資的多少,則這種情況是有狀態的,因為查詢工資的每一步操作都依賴於前一步操作,只要前置操作不成功,后續操作就無法執行;如果輸入一個url即可得到指定員工的工資,則這種情況是無狀態的,因為獲取工資不依賴於其他資源或狀態,且這種情況下,員工工資是一個資源,由一個url與之對應,可以通過HTTP中的GET方法得到資源,這是典型的RESTful風格。

三、RESTful API代碼示例

    package com.ldy.sboot.demo.controller;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.DeleteMapping;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.PutMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
     
    import com.ldy.sboot.demo.entity.OrderEntity;
    import com.ldy.sboot.demo.service.OrderService;
     
    @RequestMapping("restful/order")
    @RestController
    public class OrderController {
     
        @Autowired
        private OrderService orderService;
     
        /**
         * @描述: 根據ID查詢<br>
         * @param id
         * @return
         */
        @GetMapping(value = "{id}")
        //@RequestMapping(method = RequestMethod.GET)
        public ResponseEntity<OrderEntity> queryOrderById(@PathVariable("id") Long id) {
            try {
                OrderEntity entity = orderService.queryOrderById(id);
                if (null == entity) {
                    // 資源不存在,響應404
                    return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
                }
                // 200
                // return ResponseEntity.status(HttpStatus.OK).body(entity);
                return ResponseEntity.ok(entity);
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 500
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
     
        /**
         * @描述: 新增<br>
         * @param entity
         * @return
         */
        @PostMapping
        //@RequestMapping(method = RequestMethod.POST)
        public ResponseEntity<Void> saveOrder(OrderEntity entity) {
            try {
                orderService.saveOrder(entity);
                return ResponseEntity.status(HttpStatus.CREATED).build();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // 500
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
     
        /**
         * @描述: 修改<br>
         * @param entity
         * @return
         */
        @PutMapping
        //@RequestMapping(method = RequestMethod.PUT)
        public ResponseEntity<Void> updateOrder(OrderEntity entity) {
            try {
                orderService.updateOrder(entity);
                return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 500
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
     
        /**
         * @描述: 刪除<br>
         * @param id
         * @return
         */
        @DeleteMapping
        //@RequestMapping(method = RequestMethod.DELETE)
        public ResponseEntity<Void> deleteOrder(@RequestParam(value = "id") Long id) {
            try {
                OrderEntity entity = orderService.queryOrderById(id);
                if (null == entity) {
                    // 不存在返回404
                    return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
                }
                orderService.deleteOrderById(id);
                // 204
                return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 500
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }
     

四、 HTTP狀態碼說明
狀態碼     狀態碼英文名稱     中文描述
1開頭的狀態碼
100     Continue     繼續。客戶端應繼續其請求
101     Switching Protocols     切換協議。服務器根據客戶端的請求切換協議。只能切換到更高級的協議,例如,切換到HTTP的新版本協議
2開頭的狀態碼
200     OK     請求成功。一般用於GET與POST請求
201     Created     已創建。成功請求並創建了新的資源
202     Accepted     已接受。已經接受請求,但未處理完成
203     Non-Authoritative Information     非授權信息。請求成功。但返回的meta信息不在原始的服務器,而是一個副本
204     No Content     無內容。服務器成功處理,但未返回內容。在未更新網頁的情況下,可確保瀏覽器繼續顯示當前文檔
205     Reset Content     重置內容。服務器處理成功,用戶終端(例如:瀏覽器)應重置文檔視圖。可通過此返回碼清除瀏覽器的表單域
206     Partial Content     部分內容。服務器成功處理了部分GET請求
3開頭的狀態碼
300     Multiple Choices     多種選擇。請求的資源可包括多個位置,相應可返回一個資源特征與地址的列表用於用戶終端(例如:瀏覽器)選擇
301     Moved Permanently     永久移動。請求的資源已被永久的移動到新URI,返回信息會包括新的URI,瀏覽器會自動定向到新URI。今后任何新的請求都應使用新的URI代替
302     Found     臨時移動。與301類似。但資源只是臨時被移動。客戶端應繼續使用原有URI
303     See Other     查看其它地址。與301類似。使用GET和POST請求查看
304     Not Modified     未修改。所請求的資源未修改,服務器返回此狀態碼時,不會返回任何資源。客戶端通常會緩存訪問過的資源,通過提供一個頭信息指出客戶端希望只返回在指定日期之后修改的資源
305     Use Proxy     使用代理。所請求的資源必須通過代理訪問
306     Unused     已經被廢棄的HTTP狀態碼
307     Temporary Redirect     臨時重定向。與302類似。使用GET請求重定向
4開頭的狀態碼
400     Bad Request     客戶端請求的語法錯誤,服務器無法理解
401     Unauthorized     請求要求用戶的身份認證
402     Payment Required     保留,將來使用
403     Forbidden     服務器理解請求客戶端的請求,但是拒絕執行此請求
404     Not Found     服務器無法根據客戶端的請求找到資源(網頁)。通過此代碼,網站設計人員可設置"您所請求的資源無法找到"的個性頁面
405     Method Not Allowed     客戶端請求中的方法被禁止
406     Not Acceptable     服務器無法根據客戶端請求的內容特性完成請求
407     Proxy Authentication Required     請求要求代理的身份認證,與401類似,但請求者應當使用代理進行授權
408     Request Time-out     服務器等待客戶端發送的請求時間過長,超時
409     Conflict     服務器完成客戶端的PUT請求是可能返回此代碼,服務器處理請求時發生了沖突
410     Gone     客戶端請求的資源已經不存在。410不同於404,如果資源以前有現在被永久刪除了可使用410代碼,網站設計人員可通過301代碼指定資源的新位置
411     Length Required     服務器無法處理客戶端發送的不帶Content-Length的請求信息
412     Precondition Failed     客戶端請求信息的先決條件錯誤
413     Request Entity Too Large     由於請求的實體過大,服務器無法處理,因此拒絕請求。為防止客戶端的連續請求,服務器可能會關閉連接。如果只是服務器暫時無法處理,則會包含一個Retry-After的響應信息
414     Request-URI Too Large     請求的URI過長(URI通常為網址),服務器無法處理
415     Unsupported Media Type     服務器無法處理請求附帶的媒體格式
416     Requested range not satisfiable     客戶端請求的范圍無效
417     Expectation Failed     服務器無法滿足Expect的請求頭信息
5開頭的狀態碼
500     Internal Server Error     服務器內部錯誤,無法完成請求
501     Not Implemented     服務器不支持請求的功能,無法完成請求
502     Bad Gateway     充當網關或代理的服務器,從遠端服務器接收到了一個無效的請求
503     Service Unavailable     由於超載或系統維護,服務器暫時的無法處理客戶端的請求。延時的長度可包含在服務器的Retry-After頭信息中
504     Gateway Time-out     充當網關或代理的服務器,未及時從遠端服務器獲取請求
505     HTTP Version not supported     服務器不支持請求的HTTP協議的版本,無法完成處理

推薦文檔:https://blog.igevin.info/posts/restful-architecture-in-general/
————————————————
版權聲明:本文為CSDN博主「伊宇紫」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/LDY1016/article/details/85112631


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM