查字典

使用 HTTP 設計 REST 式 API 的主要原則:

  • REST API 是依照「資源」來設計的,而資源是指可由用戶端存取、任何類型的物件、資料或服務。

  • 資源具有「識別碼」,這是可唯一識別該資源的 URI。 例如,特定客戶訂單的 URI 可能會是:

  • 用戶端會透過交換資源的「表示法」與服務進行互動。 許多 Web API 會使用 JSON 作為交換格式。 例如,對上面所列 URI 的 GET 要求,可能會傳回此回應本文:

  • REST API 會使用統一的介面,有助於讓用戶端與服務實作分離。 對於建置在 HTTP 上的 REST API,統一的介面包括使用標準 HTTP 指令動詞在資源上執行作業。 最常見的作業是 GET、POST、PUT、PATCH 和 DELETE。

  • REST API 會使用無狀態要求模式。 HTTP 要求應該是獨立的,而且可能會以任何順序發生,因此保留多個要求之間的暫時性狀態資訊不是恰當的做法。 唯一可儲存資訊的場所是資源本身,而且每個要求都應該是不可部分完成的作業。 這個限制式可讓 Web 服務具有高度可調整性,因為在用戶端與特定伺服器之間不需要保留任何的親和性。 任何伺服器都可以處理來自任何用戶端的任何要求。 話雖如此,其他因素可能會限制延展性。 例如,許多 web 服務會寫入至後端資料存放區,這可能很難向外擴充。如需擴充資料存放區之策略的詳細資訊,請參閱 水準、垂直和功能性資料分割

  • REST API 是由表示法中包含的超媒體所推動的。 例如,以下顯示訂單的 JSON 表示法。 其中所包含的連結,可取得或更新與訂單相關的客戶。

在 2008 年時,Leonard Richardson 針對 Web API 提出了下列成熟度模型

  • 等級 0:定義一個 URI,而所有的作業對此 URI 都是 POST 要求。

  • 等級 1:針對個別資源建立不同的 URI。

  • 等級 2:使用 HTTP 方法來定義資源上的作業。

  • 等級 3:使用超媒體 (HATEOAS,如下所述)。

RFC 一致性

  • HTTP 1

  • HTTP 2

Level 3 更進一步地,支援 HATEOAS(Hypermedia As The Engine Of Application State)的概念,就類似 HTML 頁面鏈結,你可以從這個頁面得知可通往哪些頁面

HTTP 快取

General

什麼時候要做 HTTP 快取?

Cache Control 與 ETag讚 推推

ETag vs Header Expires

  • One last note about ETag - if you are using a load-balanced server setup with multiple machines running Apache you will probably want to turn off ETag generation.

  • Expires and Cache-Control are "strong caching headers"

    Last-Modified and ETag are "weak caching headers"

    First the browser check Expires/Cache-Control to determine whether or not to make a request to the server

    If have to make a request, it will send Last-Modified/ETag in the HTTP request. If the Etag value of the document matches that, the server will send a 304 code instead of 200, and no content. The browser will load the contents from its cache.

新手坑:讓人又愛又恨的HTTP Caching. https://www.facebook.com/groups/f2e.tw/posts/1486112278092799

如果 server 有負載平衡(load balance)的情況下有可能會產生不同的 Etag,這有什麼建議的作法去解決嘛?

說明清楚一點好了,這跟 server 端怎麼計算 ETag 有關,一般像 Apache/Nginx 在計算 ETag 時會用到 last modified time,如果用 load balancing 會有 ETag 不同的情況可能就是 sync 檔案時沒有同步 timestamp。 Apache 的話還要從設定排除掉參考 inode 的部份,畢竟每台機器上同一個檔案 inode 不可能一樣,詳細需要如何修改還是要看你使用的 server 環境如何。 如果是想單純從前端部份求解的話應該是沒辦法,只能當作沒有 cache 每次從 server 重新拿資料了。

Etag & Conditional Requests

Etag 和 Conditional Request 是客戶端的快取

Etag與HTTP快取機制

Etag – 工作原理

Etag由伺服器端生成,客戶端通過If-Match或者說If-None-Match這個條件判斷請求來驗證資源是否修改。常見的是使用If-None-Match.請求一個檔案的流程可能如下:

====第一次請求=== 1.客戶端發起 HTTP GET 請求一個檔案;

2.伺服器處理請求,返回檔案內容和一堆Header,當然包括Etag(例如”2e681a-6-5d044840″)(假設伺服器支援Etag生成和已經開啟了Etag).狀態碼200

====第二次請求=== 1.客戶端發起 HTTP GET 請求一個檔案,注意這個時候客戶端同時傳送一個If-None-Match頭,這個頭的內容就是第一次請求時伺服器返回的Etag:2e681a-6-5d044840

2.伺服器判斷髮送過來的Etag和計算出來的Etag匹配,因此If-None-Match為False,不返回200,返回304,客戶端繼續使用本地快取;

流程很簡單,問題是,如果伺服器又設定了Cache-Control:max-age和Expires呢,怎麼辦? 答案是同時使用,也就是說在完全匹配If-Modified-Since和If-None-Match即檢查完修改時間和Etag之後,伺服器才能返回304.

Etag & Conditional Request 用來驗證資料,也可以拿來做 API 快取。 瀏覽器第一次請求時伺服器會返回 Etag 和 200。 瀏覽器第二次請求時如果有夾帶 if-no-match + Etag,伺服器會判斷 Etag 是否相同,相同伺服器就會回傳 304 要客戶端使用本地快取。

ETag 是 HTTP 回應標頭,用來標誌資源的版本。它可以使快取機制更有效率並節省頻寬, 畢竟資料沒有變動的話,伺服器就不需要再次傳回整份資料。 而且,它還可以用來預防多人同步更新資料時覆蓋掉彼此的資料("mid-air collisions")。

如果一個網址的資源有更新,就必須重新產生它的 Etag 值。 比較前後版本的 ETag 就能知道資源有沒有變化,所以 Etags 的作用就跟指紋一樣。有些伺服器便會把它用在追蹤用途上,而且可能會永久保存這些資訊。

HTTP 快取驗證 與 條件請求 (Conditional Requests)

条件式请求可以用来验证缓存的有效性,省去不必要的控制手段,以及验证文件的完整性,

对于安全(safe)方法来说,例如 GET,通常用来获取文件,条件请求可以被用来限定仅在满足条件的情况下返回文件。这样可以节省带宽

对于非安全(unsafe)方法来说,例如 PUT 方法,通常用来上传文件,条件请求可以被用来限定仅在满足文件的初始版本与服务器上的版本相同的条件下才会将其上传。

If-Match如果远端资源的实体标签与在 ETag 这个首部中列出的值相同的话,表示条件匹配成功。默认地,除非实体标签带有 'W/' 前缀,否者它将会执行强验证。

If-None-Match如果远端资源的实体标签与在 ETag 这个首部中列出的值都不相同的话,表示条件匹配成功。默认地,除非实体标签带有 'W/' 前缀,否者它将会执行强验证。

idempotency

Understanding Idempotency and Safety in API Design

Idempotency重複做同一個動作應該得到相同結果,

Simply put, an operation is idempotent if it produces the same result when called over and over. An identical request should return an identical result when done twice, two thousand, or two million times.

status code

於現行許多API status codes不合RFC的規範,經常使用200 + error messages(我以前常用的是兩層statusCodes, 最外層200 內層資料自定義statusCode),但如需open須依照RFC(RFC 7231)規範.

可以學習的對象

Github, Google, Facebook, Twitter, Twilio

Last updated