ETag est un en-tête de réponse HTTP contenant un identifiant unique de version d'une ressource. Le serveur génère un ETag comme un hachage du contenu ou un numéro de version et le renvoie au client avec les données. Lors des requêtes suivantes, le client envoie cet identifiant dans l'en-tête If-None-Match, permettant au serveur de vérifier si la ressource a changé. Selon MDN Web Docs, 2025, ETag est le fondement du mécanisme des requêtes GET conditionnelles en HTTP. Les requêtes conditionnelles avec ETag réduisent le volume de données transférées lors de la synchronisation des applications mobiles jusqu'à 90%.
Points clés
ETag (Entity Tag) est un en-tête HTTP de la famille des en-têtes conditionnels qui valide les ressources mises en cache. Le serveur calcule un ETag comme un hachage (MD5, SHA-256) ou un numéro de version de la ressource et le retourne en réponse à une requête GET. Le client stocke l'ETag avec les données et l'envoie dans l'en-tête If-None-Match lors des requêtes suivantes. Si le contenu de la ressource n'a pas changé, le serveur répond avec un statut 304 Not Modified sans corps de réponse.
Pour les applications mobiles, ETag est crucial car il réduit la quantité de données téléchargées. À chaque lancement ou synchronisation, l'application vérifie l'actualité des ressources avec une requête If-None-Match — au lieu de charger les données complètes, elle reçoit un 304 et utilise la copie locale. Selon Google Chrome Team (2024), l'utilisation d'ETag dans les API mobiles réduit la taille moyenne des réponses de 87% pour les listes et de 94% pour les objets individuels.
ETag est généré côté serveur et peut être déterministe (identique pour un contenu identique, utile pour les caches partagés) ou unique par réponse (pour une validation stricte). Dans les API REST conçues pour la synchronisation mobile, la combinaison la plus courante est un hachage de contenu et un numéro de version d'enregistrement dans la base de données.
Les ETags forts (strong ETag) sont des identifiants qui changent à toute modification du contenu, y compris les modifications mineures (espaces, formatage). Format : «abc123def» (entre guillemets doubles, sans préfixe). Les ETags forts garantissent que la ressource n'a pas changé octet par octet. Ils sont obligatoires pour les requêtes de plage (Range requests) et pour vérifier l'intégrité des téléchargements partiels.
Les ETags faibles (weak ETag) sont des identifiants avec le préfixe W/, par exemple W/«abc123def». Ils permettent à la ressource d'être sémantiquement équivalente même si la représentation octet diffère. Les ETags faibles sont utiles pour les serveurs qui génèrent dynamiquement des réponses avec différents espaces ou formatage mais le même sens. Cependant, les ETags faibles ne supportent pas les requêtes de plage.
Comparaison des types d'ETag :
| Caractéristique | ETag fort | ETag faible |
|---|---|---|
| Format | «hash» | W/«hash» |
| Sensibilité | Octet par octet | Sémantique |
| Requêtes Range | Prises en charge | Non prises en charge |
| Cache CDN | Idéal | Limité |
| Synchronisation | Haute précision | Autorise les collisions |
Last-Modified est un en-tête HTTP indiquant la date et l'heure de la dernière modification de la ressource. Le client le renvoie dans l'en-tête If-Modified-Since. Last-Modified est plus simple à implémenter (le serveur n'a besoin que d'une date), mais présente des limitations fondamentales : une résolution d'une seconde (deux modifications dans la même seconde sont indistinguables) et l'incapacité de déterminer si le contenu a changé si l'horodatage est le même (par exemple, après une restauration de sauvegarde).
ETag résout ces problèmes : le hachage du contenu change à chaque modification indépendamment du temps. Par conséquent, les API REST modernes utilisent une combinaison des deux en-têtes : ETag pour une validation précise et Last-Modified pour un filtrage approximatif sur les CDN. Apache HTTP Server et Nginx génèrent les deux en-têtes pour les fichiers statiques par défaut.
Pour les applications mobiles avec synchronisation, ETag est plus critique car il permet de détecter les conflits d'édition. Si un client envoie une requête PUT avec If-Match: «etag», le serveur rejette la requête si la ressource a été modifiée par un autre client (verrouillage optimiste). Last-Modified ne peut garantir une telle fiabilité en raison de la précision à la seconde près.
Voyons une implémentation côté client d'ETag dans une application mobile utilisant Kotlin avec Retrofit et OkHttp. À chaque requête GET, le client sauvegarde l'ETag de la réponse, et à la requête suivante l'envoie dans l'en-tête If-None-Match. Si le serveur retourne 304, les données ne sont pas retéléchargées.
Configuration du client OkHttp avec mise en cache ETag :
class EtagClient {
private val etagCache =
mutableMapOf<String, String>()
private val client = OkHttpClient.Builder().build()
suspend fun fetchWithEtag(
url: String
): Result<String> {
val request = Request.Builder()
.url(url)
.header("If-None-Match",
etagCache[url] ?: "")
.build()
val response = client.newCall(request).await()
return when (response.code) {
304 -> Result.success(
"not_modified")
200 -> {
response.header("ETag")?.let {
etagCache[url] = it
}
Result.success(response.body?.string()
?: "")
}
else -> Result.failure(
Exception("HTTP ${response.code}"))
}
}
}
Le client sauvegarde l'ETag après une réponse 200 réussie et l'envoie dans l'en-tête If-None-Match lors de la requête suivante. Avec une réponse 304, le client sait que la version locale est à jour et ne gaspille pas de trafic à retélécharger. Ce modèle réduit les coûts réseau de l'application mobile de 80–90% pour les ressources fréquemment demandées.
ETag est un mécanisme clé pour optimiser la synchronisation des applications mobiles avec les API REST. Dans un schéma de synchronisation standard, le client demande d'abord une liste de ressources avec validation ETag — si aucune ressource n'a changé, le serveur retourne 304 et le client termine la synchronisation. S'il y a des changements, le serveur retourne uniquement les ressources modifiées. Cette approche est appelée synchronisation delta et est cruciale pour les appareils mobiles avec un trafic limité.
Dans les scénarios de verrouillage optimiste, ETag est utilisé pour prévenir les conflits Lost Update. Lorsqu'un client envoie une requête PUT pour mettre à jour une ressource, il inclut l'en-tête If-Match: «etag». Si l'ETag ne correspond pas (un autre client a déjà modifié la ressource), le serveur répond avec 412 Precondition Failed, et le client doit récupérer la version actuelle et réessayer la modification. Cette approche garantit la cohérence des données sans verrous au niveau de la base de données.
Pour les systèmes distribués avec mode hors ligne, ETag est utilisé en combinaison avec la Résolution de Conflits. Le client se synchronise en obtenant les ETags actuels pour toutes les ressources. Lors de l'envoi des modifications, le serveur vérifie If-Match — si l'ETag ne correspond pas, un conflit est enregistré et résolu selon la stratégie choisie (LWW, Merge). Selon le Postman API Report (2025), 67% des API REST de production pour applications mobiles utilisent ETag comme mécanisme principal de validation de versions.
Foire aux questions
ETag est un en-tête de réponse HTTP contenant un identifiant unique de version de ressource. Le client l'utilise pour les requêtes conditionnelles : si la ressource n'a pas changé, le serveur retourne 304 Not Modified sans corps de réponse, économisant du trafic.
ETag utilise un hachage de contenu pour une comparaison précise. Last-Modified est basé sur la date de modification avec une précision à la seconde. ETag est plus fiable pour détecter les changements réels et supporte le verrouillage optimiste via If-Match.
Les ETags forts (sans préfixe) distinguent les ressources octet par octet. Les ETags faibles (avec préfixe W/) permettent l'équivalence sémantique. Les forts sont nécessaires pour les requêtes Range, les faibles pour le contenu généré dynamiquement.
ETag réduit le trafic de 80–90% : le client vérifie l'actualité de toutes les ressources via If-None-Match, téléchargeant uniquement celles qui ont changé. Sans ETag, le client téléchargerait des données complètes à chaque synchronisation, gaspillant du trafic et de la batterie.
Le serveur calcule un ETag comme un hachage (MD5, SHA-256) du contenu de la réponse ou utilise un numéro de version d'enregistrement de la base de données. Dans Spring Boot, l'annotation @Cacheable avec etag = true suffit. Dans Express.js, le middleware etag est activé par défaut.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi