HTTPQUERY
Deutsch

428 Precondition Required

Verwendung

Der Statuscode 428 Precondition Required signalisiert, dass der Server erwartet, dass HTTP-Anfragen dieses Typs bedingt gestellt werden und einen passenden HTTP-Header wie If-Match, If-None-Match, If-Modified-Since oder If-Unmodified-Since enthalten.

Diese HTTP-Header werden von Clients optional verwendet, sofern der Server sie unterstützt; in diesem Fall jedoch verlangt der Server ihren Einsatz. Je nach Anwendungsfall soll dies Fälle von Datenverlust wie das Problem des „lost update“ verringern.

Ein verlorenes Update entsteht, wenn ein Client eine Ressource per GET abruft, sie verändert und die geänderte Fassung per PUT an den Server zurücksendet. Ohne Eingriff Dritter ist das unproblematisch. Hat jedoch nach dem ursprünglichen GET ein Dritter den Zustand der Ressource auf dem Server verändert, entsteht ein Konflikt. Setzt der Client PUT ein, ohne zuvor den Zustand der Ressource zu prüfen, wird das Update des Dritten überschrieben (ein verlorenes Update).

Indem bedingte Prüfungen mit ETags und Datumsangaben erzwungen werden, sinkt die Wahrscheinlichkeit, dass Clients Updates überschreiben, weil weniger Annahmen über den Zustand der Ressource getroffen werden.

Dies steht in Zusammenhang mit der Antwort 412 Precondition Failed, die der Server sendet, wenn eine oder mehrere der Bedingungen nicht erfüllt sind.

SEO-Auswirkung

Suchmaschinen wie Google indexieren keine URL mit dem Antwortstatus 428. Zuvor indexierte URLs, die diesen Statuscode zurückgeben, werden aus den Suchergebnissen entfernt.

Beispiel

Der Client hatte zuvor eine Kopie der Ressource abgerufen und die lokale Kopie seitdem verändert. Als der Client versucht, die Ressource per PUT zu senden und den Server zu aktualisieren, antwortet der Server mit 428 Precondition Required, weil die HTTP-Header keine bedingte Prüfung enthielten.

Anfrage

PUT /reservations.txt HTTP/1.1
Host: example.com

Antwort

HTTP/1.1 428 Precondition Required
Content-Type: text/html
Content-Length: 193

<html>
  <head>
    <title>Conditional Update Required</title>
  </head>
  <body>
   <p>This PUT request must be done conditionally.
   Try again using If-Unmodified-Since.</p>
  </body>
</html>

Behebung

Rufen Sie die Ressource zunächst mit einer GET-Anfrage ab und entnehmen Sie den ETag-Wert aus den Antwort-Headern. Senden Sie die verändernde Anfrage (PUT, PATCH oder DELETE) anschließend erneut, mit einem If-Match-Header, der auf den abgerufenen ETag-Wert gesetzt ist.

Alternativ verwenden Sie den Header If-Unmodified-Since mit dem Last-Modified-Datum aus der ursprünglichen GET-Antwort. Der Server vergleicht das Datum und fährt nur fort, wenn sich die Ressource seitdem nicht geändert hat.

Der ETag-Ansatz ist präziser. Zeitstempel haben eine Granularität von Sekunden und übersehen schnell aufeinanderfolgende Bearbeitungen. ETags ändern sich bei jeder Änderung, unabhängig vom Zeitpunkt.

Stellen Sie sicher, dass das GET zum Abrufen des ETag dieselbe Ressource adressiert wie die nachfolgende verändernde Anfrage. Ein ETag aus einem anderen Datensatz löst eine Antwort 412 Precondition Failed aus.

APIs auf Basis von SAP, Salesforce und ähnlichen Plattformen erzwingen bedingte Anfragen häufig bei Update- und Löschvorgängen. Prüfen Sie in der API-Dokumentation, welche Endpunkte Vorbedingungen verlangen und welche Validator-Header akzeptiert werden.

Auf Serverseite hilft die Antwort 428, das Problem des „lost update“ zu verhindern, bei dem zwei Clients dieselbe Ressource bearbeiten und sich gegenseitig überschreiben. Werden ETag-Header bei allen veränderlichen Ressourcen mitgeliefert, erhalten Clients die Werte, die sie für bedingte Anfragen benötigen.

Code-Referenzen

.NET

HttpStatusCode.PreconditionRequired

Rust

http::StatusCode::PRECONDITION_REQUIRED

Rails

:precondition_required

Go

http.StatusPreconditionRequired

Symfony

Response::HTTP_PRECONDITION_REQUIRED

Python3.5+

http.HTTPStatus.PRECONDITION_REQUIRED

Apache HttpComponents Core

org.apache.hc.core5.http.HttpStatus.SC_PRECONDITION_REQUIRED

Angular

@angular/common/http/HttpStatusCode.PreconditionRequired