TATECHATLAS
◎ Français
Web et API

ETag et requêtes conditionnelles : cache et modifications concurrentes

Employer If-None-Match pour revalider le cache et If-Match pour éviter d'écraser une version plus récente.

Dans ce guide

ETag identifie une représentation particulière d'une ressource. Le client renvoie la valeur reçue dans If-None-Match pour une lecture ou If-Match pour une modification. Pour GET ou HEAD, un If-None-Match correspondant peut produire 304 Not Modified et permettre de réutiliser le corps déjà enregistré. Un If-Match non satisfait produit 412 Precondition Failed : il faut alors relire la version actuelle et réconcilier les changements. Ces mécanismes répondent à des besoins différents. Un ETag ne donne aucun droit d'accès et n'autorise pas le partage du contenu d'un utilisateur avec d'autres utilisateurs.

Identifier la représentation concernée

Un ETag appartient à la représentation sélectionnée, pas simplement à son URL. Le serveur choisit sa valeur, que le client traite comme un identifiant opaque. Ce n'est pas nécessairement une empreinte de fichier, une date ou un numéro de révision. Si la réponse dépend de la langue ou d'autres en-têtes, cette sélection compte aussi. Identifiez le corps enregistré, la requête qui l'a sélectionné et le validateur reçu avec cette réponse précise.

Conserver la valeur exacte

Conservez la valeur reçue intégralement, avec ses guillemets et son éventuel préfixe W/. L'exemple utilise ETag: "version-a". Ne retirez pas les guillemets, ne reconstruisez pas la valeur à partir de l'horloge locale et ne déduisez pas un ordre des versions à partir du nom. Le serveur peut employer un autre schéma. Enregistrez le validateur avec sa représentation et évitez une valeur globale pour toutes les ressources ou toutes les langues.

HTTP/1.1 200 OK
ETag: "version-a"
Cache-Control: private, no-cache
Content-Type: application/json

{"title": "Example"}

Revalider avec If-None-Match

Quand une réponse enregistrée doit être validée, envoyez son ETag dans If-None-Match avec GET. Si la représentation correspond toujours, le serveur peut répondre 304. Sinon, il renvoie la représentation normalement, souvent avec 200 et un nouveau validateur. La revalidation réduit le transfert du corps mais nécessite encore une requête. Une réponse fraîche et réutilisable peut parfois être servie directement depuis le cache, selon sa politique, sans cette validation auprès du serveur.

GET /documents/42 HTTP/1.1
Host: example.com
If-None-Match: "version-a"

Traiter 304 sans perdre le corps

Une réponse 304 n'apporte aucun nouveau corps de représentation. Gardez le contenu précédemment enregistré et mettez à jour les métadonnées de cache pertinentes selon les en-têtes reçus. Ne remplacez pas votre document par une chaîne vide parce que la réponse réseau n'a pas de corps. Sans représentation enregistrée correspondante, l'application ne peut pas reconstruire la ressource à partir de 304 seul. Elle doit obtenir de nouveau le corps et rétablir une entrée cohérente.

HTTP/1.1 304 Not Modified
ETag: "version-a"
Cache-Control: private, no-cache

Protéger les modifications avec If-Match

Lors d'une modification, envoyez dans If-Match le validateur de la version réellement éditée. Si un autre auteur a changé la ressource, la condition peut échouer avec 412. Rechargez la représentation actuelle et réconciliez les changements plutôt que de répéter aveuglément l'écriture. Le serveur doit appliquer correctement la condition avec l'opération de mise à jour. Afficher seulement l'ETag dans l'interface ne suffit pas à empêcher la perte d'une modification concurrente.

PUT /documents/42 HTTP/1.1
Host: example.com
If-Match: "version-a"
Content-Type: application/json
Content-Length: 21

{"title": "Updated!"}

Distinguer validateurs forts et faibles

Un validateur fort représente une équivalence octet par octet. Un ETag faible, préfixé W/, autorise une équivalence plus faible. If-None-Match utilise une comparaison faible, adaptée à la revalidation du cache. If-Match utilise une comparaison forte : une valeur faible ne constitue donc pas un validateur fort correspondant pour une modification. Supprimer W/ ne fabrique pas une garantie supplémentaire. Si le service fournit seulement des valeurs faibles, utilisez un mécanisme de modification qu'il prend réellement en charge.

Définir la politique de cache

ETag ne remplace ni Cache-Control ni Vary. Cache-Control définit le comportement de mise en cache ; Vary indique quels en-têtes influencent la sélection de représentation. no-cache permet le stockage mais exige une validation avant réutilisation, alors que no-store interdit de stocker la réponse. Le contenu personnalisé exige aussi une politique adaptée aux caches privés ou partagés. Déterminez d'abord qui peut enregistrer chaque réponse et quand elle peut être réutilisée, puis ajoutez les validateurs.

Diagnostiquer les échanges conditionnels

Examinez le statut initial, ETag, Cache-Control et Vary. Comparez ensuite une lecture conditionnelle d'une ressource inchangée et d'une représentation modifiée. Pour un conflit d'écriture, inspectez la valeur de If-Match et le statut reçu. Journalisez les identifiants et les statuts plutôt que des corps sensibles. Les blocs HTTP sont des échanges illustratifs, pas un test réseau exécuté. Cette démarche distingue un corps enregistré manquant, un validateur erroné et un serveur qui n'applique pas les conditions.

Points à vérifier

  • Associer chaque ETag à la représentation exacte qu'il valide.
  • Sur 304, réutiliser le corps enregistré sans le remplacer par un corps vide.
  • Traiter 412 comme un conflit et relire avant de réessayer.
  • Vérifier ensemble Cache-Control, Vary et le caractère fort ou faible du validateur.

Le client doit conserver une représentation cohérente et le serveur doit appliquer les conditions. Ces requêtes ne fournissent ni autorisation, ni confidentialité, ni politique complète de résolution des conflits. Aucun gain de bande passante n'a été mesuré.

Sources

  1. MDN: HTTP conditional requests ↗
  2. MDN: ETag ↗
  3. RFC 9110: HTTP semantics and conditional requests ↗
  4. RFC 9111: HTTP caching ↗
Retour en haut ↑