1. 程式人生 > 實用技巧 >HTTP methods 與 RESTful API

HTTP methods 與 RESTful API

Note
GET, primarily used to select resources.
Other options for an API method include:
POST, primarily used to create child resources.
PUT, primarily used to update existing resources (and, although not recommended, can be used to create child resources).
DELETE, used to delete resources.
PATCH, used to update resources.
HEAD, primarily used
in testing scenarios. It is the same as GET but does not return the resource representation. OPTIONS, which can be used by callers to get information about available communication options for the target service. The method created is not yet integrated with the back end. The next step sets this
up.

目錄:

  1. RESTful 是什麼
  2. JSON-server (提供 RESTful API 介面 + JSON 返回資料)
  3. 如何選擇 REST 方法
  4. HTTP verbs / method (安全 | 冪等)
  5. HTTP POST V.S. PUT
  6. REST POST | PUT | PATCH

  • RESTful 是什麼阮一峰:理解RESTful架構

    • Representational State Transfer 表徵狀態轉移
    • 核心:resource。representation 指的是 resource 的表現層。
      resource,資源,即一個實體(文字/圖片/服務),可以用一個 URI 唯一標識。
    • representation,表現層
      資源,是一個實體,可以有多種外在表現形式。這個表現形式,即 representation 表現層。
      e.g. 文字可以用txt表示,也可以用 HTML/ XML/ JSON。
    • State Transfer,狀態轉移
      client <-> server,這個互動涉及到資料和狀態的變化。
      client 操作 server,即通過某種手段(HTTP method),使 server 發生狀態轉移。

    • 目前對 REST 的理解:(2016-8-20)

      • 每個 URI 代表一種資源。用名詞表示。
      • HTTP method 表示對資源進行了哪種型別的操作。
    • HTTP verbs 推薦返回的狀態碼

    • TOP10 HTTP Status Code in REST
      • 200 OK201 Created204 No Content
      • 304 Not Modified
      • 400 Bad Request401 Unauthorized403 Forbidden404 Not Found409 Conflict
      • 500 Internal Server Error
    • 水很深,現在還理解不了

JSON-Server

  • JSON-Server 是一款前端測試工具,可提供 REST API + JSON 服務。
  • 來看一組 JSON-Server 提供的 RESTful API 介面:

    GET   /posts    //獲取posts下的所有資源
    GET   /posts/1  //獲取posts下id為1的資源
    GET   /posts?title=json-server&author=typicode //獲取posts下title=json-server&author=typicode的資源
    POST  /posts   //posts新增操作,非冪等,每次都新增新的,除非已存在!
  • 建立資源成功時,應當返回201 Created而不是200 OK。同時,
  • 需要在HTTP response headers的location節中返回所建立的新資源對應的URL,
  • 同時返回該資源的內容。
    PUT   /posts/1 //對posts下id為1的資源進行修改操作:完全替換,或者不存在則新增。
    PATCH /posts/1 //對posts下id為1的資源進行修改操作:區域性更新
    DELETE   /posts/1  //對posts下id為1的資源進行刪除操作
    
  • 有這兩個明顯的特點:
    • 每個 URI 代表一種資源。用名詞表示。
    • HTTP method 表示對資源進行了哪種型別的操作。
  • 使用時需注意:

    • get
      將查詢的引數用 & 拼接成查詢字串

      if(data && Object.prototype.toString.call(data) == "[object Object]") {
          for (var i in data) {
              dataStr += i + "=" + data[i] + "&";
          }
      }
      
      lastPos = dataStr.lastIndexOf("&");
      dataStr = dataStr.slice(0, lastPos);

    • postputpatch請求中,content-type的值必須為application/json
      相應的,需要將提交的資料,由 JS物件 -> JSON JSON.stringify()

      xhr.setRequestHeader("content-type", "application/json");
      xhr.send(data ? JSON.stringify(data) : null);


  • RESTful

    RESTful 只是一種 architectural style,意思是如果大家都依此行事的話,溝通成本會很低,開發效率就高。

    那麼只要前後臺約定好,就可以隨意選取方法了麼?

    This is wrong because a request passes through many intermediaries and middleware applications which perform optimizations based on the HTTP method type. These optimizations depend on two key characteristics of HTTP methods: idempotency and safety, which are defined in the HTTP specification.
    Code Ahoy: REST Design - Choosing the Right HTTP Method

    從這個角度來說,對哪種操作使用哪種方法,取決於HTTP 方法本身的特性前後臺互動介面的約定

  • HTTP 方法的兩個關鍵特性:安全|冪等safe|idempotent

    • safe
      安全的方法被期望不會產生任何副作用(side effects)。這些操作是隻讀的。e.g. 查詢資料庫。
    • idempotent
      冪等的方法保證了重複進行一個請求和一次請求的效果相同。(並不是指返回 client 的響應總是相同的;而是指 server 上資源的狀態從第一次請求後就不再改變)
      在數學中,冪等性指N次變換和一次變換的結果相同。

      x = 1;    /* 冪等 */
      x++;      /* 非冪等 */
      

  • 安全|冪等是由 HTTP 標準定義的契約:開發者在實現 RESTful API 時必須遵守。

    • 如果一個操作沒有以冪等的方式實現,那麼即使它是通過 GET 方法呼叫的,它也不會自動變成 冪等的/ 安全的。
    • 當使用 HTTP 構建 RESTful 程式時,對HTTP method 的實現應該滿足其安全性和冪等性,來使 client 和中介軟體能自由地按契約優化,並增強使用者體驗。

      e.g. 瀏覽器並不確切知道某個特定的 form 用途,但如果這個 form 是通過 HTTP GET 提交的,瀏覽器就會知道當出現網路異常的時候,它可以安全的、自動再次嘗試提交。 而通過 HTTP POST 提交的 form,如果瀏覽器不先向使用者確認就重複提交,會是不安全的。

  • RESTful 下的postputpatch

    • post

      • 非冪等:兩次相同的POST請求會在伺服器端建立兩份資源,它們具有不同的URI。
      • POST 所對應的URI並非建立的資源本身,而是資源的接收者。比如:POST xx/articles 的語義是在 xx/articles下建立一篇帖子。
      • 從另一個角度理解 POST如何設計下單的介面?post /orders?

        本來 POST 就是被設計來提交表單這樣的事務型操作的。所以 POST 可以理解為執行伺服器的一個事務。POST 請求伺服器執行一個動作,多次發起請求可能導致動作多次執行:非冪等。

    • put
      • 冪等:對同一URI進行多次PUT的副作用和一次PUT是相同的。
      • PUT 所對應的URI是要建立或更新的資源本身。比如:PUT xx/articles/4231 的語義是建立或更新ID為4231的帖子。
    • patch
      • 非冪等 e.g.patch可以對資源進行邏輯判斷增量修改,如每次加3,那麼執行多次,就會造成額外影響。
      • 對已有資源的區域性更新(而不用指定整個資源)。

  • 有人認為應該用 POST 來建立新資源,用 PUT 來更新已有資源。如果用 POST 來做更新操作,就不符合 RESTful 風格。

  • 實際並非如此。

    The REST standard doesn’t stop us from using POST requests for updates. In fact, it doesn’t even talk about it because idempotency and safety guarantees are properties of the HTTP protocol, not of the REST standard.

    作者Code Ahoy又引用了 Roy Fielding 的話, 大意是,例如 RESTful 不使用 GET 來進行不安全的操作,是因為這會違反 HTTP 中對 GET 方法的定義,反過來就會影響中介軟體和搜尋引擎。由 HTTP 定義的方法是 Web's architecture definition 的一部分,而不屬於 REST architecture style.

  • 因此,使用 POST 還是 PUT 歸結於:這些方法的冪等性保證。

  • 因為 PUT 是冪等的,所以當第一個請求的響應沒有及時到達的時候,clients 或者中介軟體可以重複傳送 PUT 請求,而不用考慮 server 是否已經處理了第一個請求。 而為了保證冪等性,PUT 請求必須替換整個資源,因此必須傳送所有屬性。 如果要進行區域性更新,就必須使用 POST 或者 PUT 這些非冪等的方法。


  • 既然選擇 POST 還是 PUT 不屬於 REST architecture style 的範圍,而屬於 HTTP 的設計,那我們來看看兩者在 HTTP 中分別應用於什麼場景。
  • HTTP 中的 POST V.S. PUT

    The fundamental difference between the POST and PUT requests is reflected in the different meaning of the Request-URI. The URI in a POST request identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. In contrast, the URI in a PUT request identifies the entity enclosed with the request – the user agent knows what URI is intended and the server MUST NOT attempt to apply the request to some other resource.Method Definitions RFC2616

    • POST 和 PUT 最根本的區別反映在 request URI 的含義上:

      • POST 請求中的 URI,標識了要處理所附實體的資源。
      • PUT 請求的的 URI,標識了所附實體。
    • PUT

      PUT puts a file or resource at a specific URI, and exactly at that URI.

      如果這個這個 URI 所指定的位置上已有資源,PUT 就會替換掉這個資源;如果沒有, PUT 會建立一個。
      但是 PUT 請求的響應不會被快取。

    • POST

      POST sends data to a specific URI and expects the resource at that URI to handle the request.

      POST 請求的響應的是可以快取的,只要 server 設定了合適的 Cache-Control 和 Expires 首部。

      HTTP RFC指定 POST 用來:

      • Annotation of existing resources;
      • Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles;
      • Providing a block of data, such as the result of submitting a form, to a data-handling process;
      • Extending a database through an append operation.
    • 使用 REST 的好處之一就是促進了 HTTP verbs/methods 的正確使用。

    • What's the difference between a POST and a PUT HTTP REQUEST?

  • 最後來歸納一下:

    POSTto a URL creates a child resource at a server defined URL.
    PUTto a URL creates/replaces the resource in its entirety at the client defined URL.
    PATCHto a URL updates part of the resource at that client defined URL.

    • postput

      建立的物件,其URL是由 client 命名,還是 server?server 決定 -post;client 命名 -put.

      如果只是知道這個資源的父級類別的 URL,用post;(比如說建立的資源id是資料庫中自增長的);

      POST /expense-report
      

      換句話說,如果知道將要建立的資源的 URL,用put

      PUT  /expense-report/10929
      

      put是建立時的一個候選方法:當 client 在資源建立前就已經知道了它的URL。

    • putpatch

      • put用來對已知資源做完全替換,要求前端提供一個完整的資源物件,缺了的欄位會被清空。
      • patch做區域性更新,後臺只會更新接收到的欄位。【節省頻寬】
    • ref:

http://www.cnblogs.com/xhz-dalalala/p/5791631.html