對於 REST 端點,開發人員通常想要控制更新是建立新記錄還是只修改現有記錄。
If-Match HTTP 標頭會在資料 API 產生器 (DAB) 中提供該控制項。
依預設,DAB 會將 和 PATCH 視為PUT更新插入作業:
如果資源存在:它已更新。
如果不存在:已插入。
-
PUT→完整更新插入 (取代資源)。 -
PATCH→增量更新插入 (套用部分更新)。
-
新增會 If-Match: * 將此行為變更為僅限更新語意。
If-Match 在 DAB 中做什麼
If-Match 僅支援萬用字元值 *。
| 標題值 | 行為 |
|---|---|
If-Match: * |
只有在資源存在時才執行更新;如果遺失→ 404 未找到。 |
If-Match: <any other> |
被拒絕;400 錯誤請求 (Etags not supported, use '*')。 |
| (缺席) | 更新插入行為(如果找不到則插入,否則更新)。 |
行為概觀
- DAB 不會實作每筆記錄的 ETag 或版本比對。
- 不會評估並行權杖。
*只斷言「必須存在」。 - 僅適用於 REST,不適用於 GraphQL。
- 目前對 DELETE 作業沒有意義。
將 If-Match 與 PUT 搭配使用
如果沒有 If-Match,PUT 會在資源不存在時插入 (傳回 201 Created)。
僅限更新範例
Request
PUT /api/Books/id/1
If-Match: *
Content-Type: application/json
{
"title": "The Return of the King"
}
成功 (記錄已存在)
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 1,
"title": "The Return of the King"
}
失敗 (缺少記錄)
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": "No Update could be performed, record not found"
}
更新插入範例 (沒有 If-Match 且記錄不存在)
Request
PUT /api/Books/id/500
Content-Type: application/json
{
"title": "Inserted via PUT",
"publisher_id": 7
}
回應
HTTP/1.1 201 Created
Location: id/500
Content-Type: application/json
{
"id": 500,
"title": "Inserted via PUT",
"publisher_id": 7
}
將 If-Match 與 PATCH 搭配使用
PATCH 行為類似。 如果沒有 If-Match,它會執行增量更新插入。 使用 If-Match: *,它只會更新現有的資料列。
Request
PATCH /api/Books/id/1
If-Match: *
Content-Type: application/json
{
"title": "The Two Towers"
}
成功時的回應
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 1,
"title": "The Two Towers"
}
找不到時的回應
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": "No Update could be performed, record not found"
}
無效的 If-Match 使用方式
除 (包括引號字串) 以外的 * 任何值都會被拒絕。
Request
PUT /api/Books/id/1
If-Match: "abc123"
Content-Type: application/json
{
"title": "To Kill a Mockingbird"
}
回應
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "Etags not supported, use '*'"
}
Review
- 省略
If-Match更新插入 (插入或更新) 語意。 - 用於
If-Match: *嚴格的僅限更新語意 (如果缺少專案,則為 404)。 - 請勿使用任何其他值。 未實作真正的 ETag 比對。