HTTP-If-Unmodified-Since-Header

Typ

Der If-Unmodified-Since-Header ist ein Conditional-Request-Header, der eine State-ändernde Operation nur ausführt, wenn die Ressource seit dem angegebenen Zeitstempel unverändert blieb.

Syntax

Der Header enthält einen HTTP-Date-Timestamp im RFC 5322-Format (GMT-Zeitzone) als Precondition.

http
If-Unmodified-Since: Wed, 21 Oct 2025 07:28:00 GMT
If-Unmodified-Since: Sat, 01 Jan 2025 00:00:00 GMT

Direktiven

Der If-Unmodified-Since-Header akzeptiert ausschließlich einen HTTP-Date-Wert und wird primär bei State-ändernden Methoden (PUT, PATCH, DELETE, POST) verwendet.

http-date
Ein RFC 5322-konformer Zeitstempel in GMT-Zeitzone, der die erwartete maximale Last-Modified-Zeit der Ressource angibt.
state-changing-methods
Der Header ist primär für PUT, PATCH, DELETE und POST gedacht, wird bei GET ignoriert.

Beispiele

Die folgenden Beispiele zeigen typische Anwendungsfälle für Lost-Update-Prevention, konfliktfreie Updates und Zeitstempel-basierte Concurrency Control.

Lost-Update-Prevention bei REST-Update

Ein Client aktualisiert eine Ressource nur, wenn sie seit dem letzten Read unverändert blieb.

http
PUT /api/v1/products/12345 HTTP/1.1
Host: api.example.com
If-Unmodified-Since: Wed, 15 Sep 2025 10:00:00 GMT
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

{
  "name": "Premium Widget Pro",
  "price": 199.99,
  "stock": 50
}

Response bei erfolgreicher Precondition:

http
HTTP/1.1 200 OK
Last-Modified: Tue, 01 Oct 2025 11:00:00 GMT
ETag: "a7f3b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9"
Content-Type: application/json

{
  "id": "12345",
  "name": "Premium Widget Pro",
  "updatedAt": "2025-10-01T11:00:00Z"
}

Response bei Precondition-Failure (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": "Resource modified at 2025-09-20T14:30:00Z, after your If-Unmodified-Since timestamp"
}

Conditional DELETE mit Zeitstempel-Validierung

Ein Client löscht eine Ressource nur, wenn sie seit einem bestimmten Zeitpunkt unverändert blieb.

http
DELETE /api/v1/campaigns/98765 HTTP/1.1
Host: api.example.com
If-Unmodified-Since: Mon, 30 Sep 2025 08:00:00 GMT
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Batch-Update mit Precondition

Ein Batch-Job aktualisiert Ressourcen nur, wenn sie innerhalb eines bestimmten Zeitfensters nicht modifiziert wurden.

http
PATCH /api/v1/inventory/sku-42 HTTP/1.1
Host: api.example.com
If-Unmodified-Since: Tue, 01 Oct 2025 00:00:00 GMT
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

{
  "stock": 100,
  "lastInventoryCheck": "2025-10-01T10:00:00Z"
}

Conditional-Update-Flow

Der If-Unmodified-Since-Header ermöglicht Zeitstempel-basierte Concurrency Control für State-ändernde Operationen.

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/products/123
api -> db: SELECT * FROM products\nWHERE id = 123
db --> api: Product Data\nLast-Modified: 2025-09-15 10:00:00
api --> clientA: 200 OK\nLast-Modified: Wed, 15 Sep 2025 10:00:00 GMT\n{"price": 99.99}

clientB -> api: GET /api/products/123
api -> db: SELECT * FROM products\nWHERE id = 123
db --> api: Product Data\nLast-Modified: 2025-09-15 10:00:00
api --> clientB: 200 OK\nLast-Modified: Wed, 15 Sep 2025 10:00:00 GMT\n{"price": 99.99}

clientA -> api: PUT /api/products/123\nIf-Unmodified-Since: Wed, 15 Sep 2025 10:00:00 GMT\n{"price": 89.99}
api -> db: SELECT last_modified\nFROM products\nWHERE id = 123
db --> api: 2025-09-15 10:00:00
api -> api: Timestamp check:\nUNMODIFIED since cutoff
api -> db: UPDATE products\nSET price = 89.99,\nlast_modified = NOW()\nWHERE id = 123
db --> api: 1 row updated\nNew Last-Modified: 2025-10-01 11:00:00
api --> clientA: 200 OK\nLast-Modified: Tue, 01 Oct 2025 11:00:00 GMT

clientB -> api: PUT /api/products/123\nIf-Unmodified-Since: Wed, 15 Sep 2025 10:00:00 GMT\n{"price": 79.99}
api -> db: SELECT last_modified\nFROM products\nWHERE id = 123
db --> api: 2025-10-01 11:00:00\n(Modified by Client A)
api -> api: Timestamp check:\nMODIFIED after cutoff\n(2025-10-01 > 2025-09-15)
api --> clientB: 412 Precondition Failed\n{"error": "Resource modified"}

note over clientB: Client B muss\nRessource neu laden\nund Update wiederholen
@enduml

Vorteile für die Systemarchitektur

  • Lost-Update-Prevention durch Zeitstempel-basierte Preconditions
  • Einfachere Alternative zu ETag-basiertem If-Match bei Last-Modified-Support
  • Explizite Konflikt-Erkennung via 412 Precondition Failed
  • Kombinierbar mit If-Match für robuste Concurrency Control
  • Geeignet für Ressourcen ohne ETag-Unterstützung

Spezifikation

RFC 9110 (HTTP Semantics) definiert den If-Unmodified-Since-Header als Conditional-Request-Mechanismus für Zeitstempel-basierte Precondition-Validierung bei State-ändernden Operationen.

Weitere Spezifikationen

Last-Modified Header, HTTP Status 412 - Precondition Failed, If-Modified-Since Header