Skip to content
ADP
API Design PrincipleBETA

[ADP-131] If-Match

reviewing phase 1

解釋為什麼不能使用弱ETag

概述

If-Match 標頭是 HTTP 中用於基於資源當前 ETag 值進行條件請求的標頭。它主要用於防止並發修改中的"丟失更新"問題,並確保 PUT、PATCH 或 DELETE 操作中的數據完整性。

目的

If-Match 標頭的主要目的是:

  1. 防止同時更新相互覆蓋("丟失更新"問題)。
  2. 確保自上次檢索以來資源未被修改。
  3. 在 RESTful API 中實現樂觀並發控制。

指導原則

  • 伺服器必須(MUST)支援 PUT、PATCH 和 DELETE 操作中的 If-Match 標頭,以防止"丟失更新"問題。

  • 客戶端應該(SHOULD)在修改或刪除資源的請求中包含 If-Match 標頭,以確保數據完整性。

  • 如果 ETag 與提供的 If-Match 值不匹配,伺服器必須(MUST)回應 412 (Precondition Failed) 狀態碼。

  • 實現應該(SHOULD)使用強 ETag 與 If-Match 配合使用,以獲得更好的精確度。

  • 伺服器必須(MUST)在 GET 回應中包含當前的 ETag,以允許客戶端在後續的條件請求中使用它。

  • API 開發者應該(SHOULD)在伺服器端實現適當的 ETag 生成和處理。

  • 對於 412 狀態碼的錯誤回應應該(SHOULD)包含清晰的錯誤訊息,以幫助客戶端理解失敗原因。

  • 根據 RFC 7232,客戶端不得(MUST NOT)在 If-Match 標頭中使用弱 ETag。

  • 伺服器應該(SHOULD)支援在單個 If-Match 標頭中使用多個 ETag 值。

  • API 文件必須(MUST)清楚地解釋 If-Match 在 API 上下文中的行為和用法。

使用方式

If-Match 標頭可以通過以下方式使用:

  1. 使用特定的 ETag 值:

    http
    If-Match: "123456789"
  2. 使用多個 ETag 值:

    http
    If-Match: "123456789", "abcdefghijk"
  3. 使用通配符值(匹配任何 ETag):

    http
    If-Match: *

行為

  • 如果資源的 ETag 與 If-Match 標頭中的值匹配,服務器正常處理請求。
  • 如果 ETag 不匹配,服務器應該回應 412(前提條件失敗)狀態碼。
  • 如果資源不存在且 If-Match 標頭使用通配符(*),服務器應該回應 412(前提條件失敗)狀態碼。

最佳實踐

  1. 始終將 If-Match 與 ETag 結合使用於 PUT、PATCH 和 DELETE 操作,以防止丟失更新。
  2. 在服務器端實現適當的 ETag 生成和處理。
  3. 使用強 ETag 而不是弱 ETag 與 If-Match 搭配,以獲得更好的精確度。
  4. 在 GET 回應中包含當前 ETag,以允許客戶端在後續條件請求中使用它。
  5. 在 API 實現中正確處理 If-Match 標頭,以確保數據完整性。

示例

http
PUT /users/123 HTTP/1.1
Host: api.example.com
If-Match: "abc123"
Content-Type: application/json
{
  "name": "John Doe",
  "email": "john@example.com"
}

在此示例中,只有當資源的當前 ETag 匹配 "abc123" 時,才會處理 PUT 請求。

相關 ADPs

參考資料