[ADP-131] If-Match
reviewing phase 1
解釋為什麼不能使用弱ETag
概述
If-Match
標頭是 HTTP 中用於基於資源當前 ETag 值進行條件請求的標頭。它主要用於防止並發修改中的"丟失更新"問題,並確保 PUT、PATCH 或 DELETE 操作中的數據完整性。
目的
If-Match
標頭的主要目的是:
- 防止同時更新相互覆蓋("丟失更新"問題)。
- 確保自上次檢索以來資源未被修改。
- 在 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
標頭可以通過以下方式使用:
使用特定的 ETag 值:
httpIf-Match: "123456789"
使用多個 ETag 值:
httpIf-Match: "123456789", "abcdefghijk"
使用通配符值(匹配任何 ETag):
httpIf-Match: *
行為
- 如果資源的 ETag 與
If-Match
標頭中的值匹配,服務器正常處理請求。 - 如果 ETag 不匹配,服務器應該回應 412(前提條件失敗)狀態碼。
- 如果資源不存在且
If-Match
標頭使用通配符(*),服務器應該回應 412(前提條件失敗)狀態碼。
最佳實踐
- 始終將
If-Match
與 ETag 結合使用於 PUT、PATCH 和 DELETE 操作,以防止丟失更新。 - 在服務器端實現適當的 ETag 生成和處理。
- 使用強 ETag 而不是弱 ETag 與
If-Match
搭配,以獲得更好的精確度。 - 在 GET 回應中包含當前 ETag,以允許客戶端在後續條件請求中使用它。
- 在 API 實現中正確處理
If-Match
標頭,以確保數據完整性。
示例
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 請求。