ETag — een HTTP-antwoordheader met een unieke identificatie van de resourceversie. De server genereert ETag als een hash van de inhoud of versienummer en retourneert deze samen met de gegevens aan de client. Bij volgende verzoeken stuurt de client deze identificatie in de If-None-Match-header, zodat de server kan controleren of de resource is gewijzigd. Volgens MDN Web Docs, 2025 vormt ETag de basis van het mechanisme voor conditionele GET-verzoeken in HTTP. Conditionele verzoeken met ETag verminderen de hoeveelheid verzonden gegevens bij synchronisatie van mobiele apps met tot 90%.
Belangrijkste punten
ETag (Entity Tag) — HTTP-header uit de familie van conditionele headers die validatie van gecachte resources mogelijk maakt. De server berekent ETag als een hashsom (MD5, SHA-256) of versienummer van de resource en retourneert deze in het antwoord op een GET-verzoek. De client slaat ETag samen met de gegevens op en stuurt deze bij een volgend verzoek in de If-None-Match-header. Als de inhoud van de resource niet is gewijzigd, antwoordt de server met status 304 Not Modified zonder antwoordbody.
Voor mobiele apps is ETag van cruciaal belang omdat het de hoeveelheid te downloaden gegevens vermindert. Bij elke start of synchronisatie controleert de app de actualiteit van resources met een If-None-Match-verzoek — in plaats van volledige gegevens te downloaden, ontvangt het 304 en gebruikt de lokale kopie. Volgens Google Chrome Team (2024) vermindert het gebruik van ETag in mobiele API's het gemiddelde antwoordvolume met 87% voor lijsten en met 94% voor afzonderlijke objecten.
ETag wordt aan de serverzijde gegenereerd en kan zowel deterministisch (hetzelfde voor dezelfde inhoud, handig voor gedeelde caches) als uniek voor elk antwoord (voor strikte validatie) zijn. In REST API's bedoeld voor mobiele synchronisatie wordt meestal een combinatie van een inhoudshash en het versienummer van het record in de database gebruikt.
Sterke ETag (strong ETag) — identificaties die veranderen bij elke wijziging van de inhoud, inclusief kleine (spaties, opmaak). Formaat: "abc123def" (tussen aanhalingstekens, zonder prefix). Sterke ETag's garanderen dat de resource byte-voor-byte niet is gewijzigd. Ze zijn verplicht voor bereikverzoeken (Range requests) en voor het controleren van de integriteit van gedeeltelijke downloads.
Zwakke ETag (weak ETag) — identificaties met prefix W/, bijvoorbeeld W/"abc123def". Ze staan toe dat de resource semantisch equivalent is, zelfs als de byte-weergave verschilt. Zwakke ETag's zijn handig voor servers die dynamisch antwoorden genereren met verschillende spaties of opmaak maar dezelfde betekenis. Zwakke ETag's ondersteunen echter geen bereikverzoeken.
Vergelijking van ETag-soorten:
| Kenmerk | Sterke ETag | Zwakke ETag |
|---|---|---|
| Formaat | "hash" | W/"hash" |
| Gevoeligheid | Byte-voor-byte | Semantisch |
| Bereikverzoeken | Ondersteund | Niet ondersteund |
| CDN-caching | Ideaal | Beperkt |
| Synchronisatie | Hoge precisie | Staat botsingen toe |
Last-Modified — HTTP-header die de datum en tijd van de laatste wijziging van de resource aangeeft. De client stuurt deze terug in de If-Modified-Since-header. Last-Modified is eenvoudiger te implementeren (de server heeft alleen de datum nodig), maar heeft fundamentele beperkingen: een resolutie van één seconde (twee wijzigingen in één seconde zijn niet te onderscheiden) en onmogelijkheid om te bepalen of de inhoud is gewijzigd bij dezelfde tijd (bijvoorbeeld na herstel uit een back-up).
ETag lost deze problemen op: de inhoudshash verandert bij elke wijziging onafhankelijk van de tijd. Daarom gebruiken moderne REST API's een combinatie van beide headers: ETag voor precieze validatie en Last-Modified voor benaderende filtering op CDN's. Apache HTTP Server en Nginx genereren standaard beide headers voor statische bestanden.
Voor mobiele apps met synchronisatie is ETag kritischer omdat het bewerkingsconflicten kan detecteren. Als de client een PUT-verzoek stuurt met de If-Match: "etag"-header, wijst de server het verzoek af als de resource door een andere client is gewijzigd (optimistisch slot). Last-Modified kan vanwege de secondeprecisie geen dergelijke betrouwbaarheid garanderen.
Laten we de clientimplementatie van ETag in een mobiele app in Kotlin bekijken met Retrofit en OkHttp. Bij elk GET-verzoek slaat de client de ETag uit het antwoord op en bij het volgende verzoek stuurt hij deze in de If-None-Match-header. Als de server 304 retourneert, worden de gegevens niet opnieuw gedownload.
Configuratie van de OkHttp-client met ETag-caching:
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}"))
}
}
}
De client slaat de ETag op na een succesvol 200-antwoord en stuurt deze in de If-None-Match-header bij het volgende verzoek. Bij 304 weet de client dat de lokale versie actueel is en verspilt geen verkeer aan het opnieuw downloaden van gegevens. Dit patroon vermindert de netwerkkosten van de mobiele app met 80–90% voor veelgevraagde resources.
ETag is een sleutelmechanisme voor het optimaliseren van synchronisatie van mobiele apps met REST API. In het standaard synchronisatieschema vraagt de client eerst de lijst met resources op met ETag-validatie — als geen enkele resource is gewijzigd, retourneert de server 304 en beëindigt de client de synchronisatie. Als er wijzigingen zijn, retourneert de server alleen de gewijzigde resources. Deze aanpak heet deltasynchronisatie en is cruciaal voor mobiele apparaten met beperkt verkeer.
In scenario's met optimistisch slot wordt ETag gebruikt om Lost Update-conflicten te voorkomen. Wanneer de client een PUT-verzoek stuurt om een resource bij te werken, voegt hij de If-Match: "etag"-header toe. Als de ETag niet overeenkomt (een andere client heeft de resource al gewijzigd), antwoordt de server met 412 Precondition Failed en moet de client de actuele versie opnieuw downloaden en de wijziging herhalen. Deze aanpak zorgt voor gegevensconsistentie zonder vergrendelingen op databaseniveau.
Voor gedistribueerde systemen met offlinemodus wordt ETag gebruikt in combinatie met Conflict Resolution. De client synchroniseert door de huidige ETag's voor alle resources op te halen. Bij het verzenden van wijzigingen controleert de server If-Match — als de ETag niet overeenkomt, wordt een conflict geregistreerd dat wordt opgelost volgens de gekozen strategie (LWW, Merge). Volgens Postman API Report (2025) gebruikt 67% van de productie-REST API's voor mobiele apps ETag als het primaire validatiemechanisme voor versies.
Veelgestelde vragen
ETag — HTTP-antwoordheader met een unieke identificatie van de resourceversie. De client gebruikt deze voor conditionele verzoeken: als de resource niet is gewijzigd, retourneert de server 304 Not Modified zonder antwoordbody, wat verkeer bespaart.
ETag gebruikt een inhoudshash voor nauwkeurige vergelijking. Last-Modified is gebaseerd op de wijzigingsdatum met een precisie van één seconde. ETag is betrouwbaarder voor het detecteren van daadwerkelijke wijzigingen en ondersteunt optimistisch slot via If-Match.
Sterke ETag's (zonder prefix) onderscheiden resources byte-voor-byte. Zwakke ETag's (met prefix W/) staan semantische gelijkwaardigheid toe. Sterke zijn vereist voor bereikverzoeken, zwakke voor dynamisch gegenereerde inhoud.
ETag vermindert verkeer met 80–90%: de client controleert de actualiteit van alle resources via If-None-Match en downloadt alleen gewijzigde resources. Zonder ETag zou de client bij elke synchronisatie volledige gegevens downloaden, wat verkeer en batterij verspilt.
De server berekent ETag als hash (MD5, SHA-256) van de antwoordinhoud of gebruikt het versienummer van het record in de database. In Spring Boot is de annotatie @Cacheable met etag = true voldoende. In Express.js is de etag-middleware standaard ingeschakeld.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook