HTTPQUERY
Français

428 Precondition Required

Utilisation

Le code de statut 428 Precondition Required signale que le serveur attend que les requêtes HTTP de ce type soient conditionnelles et comportent un en-tête HTTP approprié tel que If-Match, If-None-Match, If-Modified-Since ou If-Unmodified-Since.

Ces en-têtes HTTP sont utilisés de façon facultative par les clients lorsque le serveur les prend en charge, mais, dans ce cas précis, le serveur en exige l’usage. Selon le cas d’usage, l’objectif est de réduire les pertes de données telles que le problème de la « mise à jour perdue ».

Une mise à jour perdue survient lorsqu’un client utilise GET pour obtenir une ressource, la modifie, puis utilise PUT pour renvoyer la version modifiée au serveur. Sans intervention d’un tiers, il n’y a aucun problème. Si, après le GET initial, un tiers a modifié l’état de la ressource sur le serveur, un conflit apparaît. Si le client utilise PUT sans vérifier au préalable l’état de la ressource, la mise à jour du tiers est écrasée (une mise à jour perdue).

En imposant des tests conditionnels fondés sur les ETags et les dates, on réduit les occasions pour les clients d’écraser des mises à jour, car moins d’hypothèses sont faites sur l’état de la ressource.

Cela est lié à la réponse 412 Precondition Failed, envoyée par le serveur lorsqu’une ou plusieurs des conditions ne sont pas satisfaites.

Impact SEO

Les moteurs de recherche comme Google n’indexeront pas une URL renvoyant un statut de réponse 428. Les URL précédemment indexées qui renvoient ce code de statut seront retirées des résultats de recherche.

Exemple

Le client avait précédemment obtenu une copie de la ressource et a depuis modifié sa copie locale. Lorsque le client tente d’envoyer la ressource par PUT pour mettre à jour le serveur, celui-ci répond 428 Precondition Required parce que les en-têtes HTTP ne comportaient aucun test conditionnel.

Requête

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

Réponse

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>

Comment corriger

Récupérez d’abord la ressource avec une requête GET et extrayez la valeur de l’ETag des en-têtes de la réponse. Renvoyez ensuite la requête de modification (PUT, PATCH ou DELETE) avec un en-tête If-Match réglé sur la valeur d’ETag récupérée.

Vous pouvez aussi utiliser l’en-tête If-Unmodified-Since avec la date Last-Modified issue de la réponse au GET initial. Le serveur compare la date et ne poursuit que si la ressource n’a pas changé depuis.

L’approche fondée sur l’ETag est plus précise. Les horodatages ont une granularité d’une seconde et manquent les modifications rapprochées. Les ETags changent à chaque modification, quel que soit le rythme.

Assurez-vous que le GET utilisé pour récupérer l’ETag cible la même ressource que la requête de modification ultérieure. Utiliser l’ETag d’un autre enregistrement déclenche une réponse 412 Precondition Failed.

Les API bâties sur SAP, Salesforce et des plateformes similaires imposent couramment des requêtes conditionnelles pour les opérations de mise à jour et de suppression. Consultez la documentation de l’API pour savoir quels points de terminaison exigent des préconditions et quels en-têtes de validation sont acceptés.

Côté serveur, la réponse 428 aide à prévenir le problème de la « mise à jour perdue », où deux clients éditant la même ressource s’écrasent mutuellement. Inclure des en-têtes ETag sur toutes les ressources modifiables donne aux clients les valeurs dont ils ont besoin pour les requêtes conditionnelles.

Références de code

.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