HTTP-If-Match-Header

Typ

Der If-Match-Header ist ein Conditional-Request-Header, der eine Anfrage nur ausführt, wenn die Ressource dem angegebenen ETag entspricht.

Syntax

Der Header enthält einen oder mehrere ETags oder das Wildcard-Symbol für beliebige Ressourcenversionen.

http
If-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
If-Match: "v1", "v2", "v3"

Direktiven

Der If-Match-Header akzeptiert entweder spezifische ETag-Werte in Anführungszeichen oder das Wildcard-Symbol für existierende Ressourcen.

etag-value
Ein oder mehrere ETag-Werte, die mit dem aktuellen ETag der Ressource übereinstimmen müssen (Strong Validators).
wildcard
Das Symbol * matcht jede existierende Ressourcenversion, schlägt jedoch fehl, wenn die Ressource nicht existiert.

Beispiele

Die folgenden Beispiele zeigen typische Anwendungsfälle für Optimistic Locking in REST-APIs, konfliktfreie Updates und Lost-Update-Prevention.

Optimistic Locking bei REST-Update

Ein Client aktualisiert eine Ressource nur, wenn die Version noch unverändert ist (Lost-Update-Prevention).

http
PUT /api/v1/orders/12345 HTTP/1.1
Host: api.example.com
If-Match: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

{
  "status": "shipped",
  "trackingNumber": "1Z999AA10123456784"
}

Response bei erfolgreichem Match:

http
HTTP/1.1 200 OK
ETag: "8f4e5c3a2b1d6f7e9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f"
Content-Type: application/json

{
  "id": "12345",
  "status": "shipped",
  "updatedAt": "2025-10-01T10:30:00Z"
}

Response bei ETag-Mismatch (Concurrent Modification):

http
HTTP/1.1 412 Precondition Failed
Content-Type: application/problem+json

{
  "type": "https://api.example.com/errors/precondition-failed",
  "title": "Resource was modified",
  "status": 412,
  "detail": "The resource has been modified since your last read. Please refresh and retry."
}

Conditional Delete mit If-Match

Ein Client löscht eine Ressource nur, wenn sie noch in der erwarteten Version vorliegt.

http
DELETE /api/v1/products/98765 HTTP/1.1
Host: api.example.com
If-Match: "d3b07384d113edec49eaa6238ad5ff00"
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Wildcard-Match für beliebige Version

Ein Client führt eine Operation nur aus, wenn die Ressource existiert, unabhängig von der spezifischen Version.

http
PUT /api/v1/inventory/sku-42/lock HTTP/1.1
Host: api.example.com
If-Match: *
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

{
  "lockDuration": 300,
  "reason": "inventory-count"
}

Optimistic-Locking-Flow

Der If-Match-Header ermöglicht Optimistic Concurrency Control durch ETag-Validierung vor State-Änderungen.

plantuml
@startuml
!theme plain
skinparam BoxPadding 20
skinparam ParticipantPadding 20

participant "Client A" as clientA
participant "Client B" as clientB
participant "API\nServer" as api
database "Database" as db

clientA -> api: GET /api/orders/123
api -> db: SELECT * FROM orders\nWHERE id = 123
db --> api: Order Data (Version 1)
api --> clientA: 200 OK\nETag: "v1"\n{"status": "pending"}

clientB -> api: GET /api/orders/123
api -> db: SELECT * FROM orders\nWHERE id = 123
db --> api: Order Data (Version 1)
api --> clientB: 200 OK\nETag: "v1"\n{"status": "pending"}

clientA -> api: PUT /api/orders/123\nIf-Match: "v1"\n{"status": "processing"}
api -> db: UPDATE orders SET status = 'processing'\nWHERE id = 123 AND etag = 'v1'
db --> api: 1 row updated (Version 2)
api --> clientA: 200 OK\nETag: "v2"

clientB -> api: PUT /api/orders/123\nIf-Match: "v1"\n{"status": "cancelled"}
api -> db: UPDATE orders SET status = 'cancelled'\nWHERE id = 123 AND etag = 'v1'
db --> api: 0 rows updated\n(ETag mismatch)
api --> clientB: 412 Precondition Failed\n{"error": "Resource modified"}

note over clientB: Client B muss Ressource\nerneut laden und\nUpdate wiederholen
@enduml

Vorteile für die Systemarchitektur

  • Optimistic Concurrency Control ohne Datenbank-Locks
  • Prevention von Lost-Updates in verteilten REST-APIs
  • Explizite Konflikt-Erkennung via 412 Precondition Failed
  • Kombinierbar mit Strong ETags für byte-genaue Validierung
  • Performance-Vorteil gegenüber Pessimistic Locking

Spezifikation

RFC 9110 (HTTP Semantics) definiert den If-Match-Header als Conditional-Request-Mechanismus für ETag-basierte Precondition-Validierung.

Weitere Spezifikationen

ETag Header, HTTP Status 412 - Precondition Failed, If-None-Match Header