ETag é um cabeçalho de resposta HTTP que contém um identificador único de versão de um recurso. O servidor gera um ETag como um hash de conteúdo ou número de versão e o retorna ao cliente junto com os dados. Em requisições subsequentes, o cliente envia este identificador no cabeçalho If-None-Match, permitindo que o servidor verifique se o recurso mudou. De acordo com MDN Web Docs, 2025, o ETag é a base do mecanismo de requisições GET condicionais em HTTP. Requisições condicionais com ETag reduzem o volume de dados transferidos durante a sincronização de aplicações móveis em até 90%.
Principais pontos
ETag (Entity Tag) é um cabeçalho HTTP da família de cabeçalhos condicionais que valida recursos em cache. O servidor calcula um ETag como um hash (MD5, SHA-256) ou um número de versão do recurso e o retorna em resposta a uma requisição GET. O cliente armazena o ETag junto com os dados e o envia no cabeçalho If-None-Match em requisições subsequentes. Se o conteúdo do recurso não mudou, o servidor responde com um status 304 Not Modified sem corpo de resposta.
Para aplicações móveis, o ETag é criticamente importante porque reduz a quantidade de dados baixados. Em cada inicialização ou sincronização, o aplicativo verifica a atualidade dos recursos com uma requisição If-None-Match — em vez de carregar dados completos, ele recebe um 304 e usa a cópia local. De acordo com o Google Chrome Team (2024), o uso de ETag em APIs móveis reduz o tamanho médio da resposta em 87% para listas e 94% para objetos individuais.
O ETag é gerado no lado do servidor e pode ser determinístico (idêntico para conteúdo idêntico, útil para caches compartilhados) ou único por resposta (para validação rigorosa). Em APIs REST projetadas para sincronização móvel, a combinação mais comum é um hash de conteúdo e um número de versão do registro no banco de dados.
ETags fortes (strong ETag) são identificadores que mudam com qualquer modificação de conteúdo, incluindo as insignificantes (espaços, formatação). Formato: “abc123def” (entre aspas duplas, sem prefixo). ETags fortes garantem que o recurso não mudou byte a byte. Eles são obrigatórios para requisições de intervalo (Range requests) e para verificar a integridade de downloads parciais.
ETags fracos (weak ETag) são identificadores com o prefixo W/, por exemplo W/“abc123def”. Eles permitem que o recurso seja semanticamente equivalente mesmo se a representação de bytes for diferente. ETags fracos são úteis para servidores que geram dinamicamente respostas com diferentes espaços ou formatação, mas com o mesmo significado. No entanto, ETags fracos não suportam requisições de intervalo.
Comparação dos tipos de ETag:
| Característica | ETag forte | ETag fraco |
|---|---|---|
| Formato | “hash” | W/“hash” |
| Sensibilidade | Byte a byte | Semântica |
| Requisições Range | Suportadas | Não suportadas |
| Cache CDN | Ideal | Limitado |
| Sincronização | Alta precisão | Permite colisões |
Last-Modified é um cabeçalho HTTP que indica a data e hora da última modificação do recurso. O cliente o envia de volta no cabeçalho If-Modified-Since. Last-Modified é mais simples de implementar (o servidor só precisa de uma data), mas tem limitações fundamentais: resolução de um segundo (duas alterações no mesmo segundo são indistinguíveis) e a incapacidade de determinar se o conteúdo mudou se o timestamp for o mesmo (por exemplo, após restaurar um backup).
ETag resolve estes problemas: o hash do conteúdo muda com qualquer modificação independentemente do tempo. Portanto, APIs REST modernas usam uma combinação de ambos os cabeçalhos: ETag para validação precisa e Last-Modified para filtragem aproximada em CDN. Apache HTTP Server e Nginx geram ambos os cabeçalhos para arquivos estáticos por padrão.
Para aplicações móveis com sincronização, o ETag é mais crítico porque permite detectar conflitos de edição. Se um cliente envia uma requisição PUT com If-Match: “etag”, o servidor rejeita a requisição se o recurso foi modificado por outro cliente (bloqueio otimista). Last-Modified não pode garantir tal confiabilidade devido à precisão de segundo nível.
Vejamos uma implementação do lado do cliente de ETag em um aplicativo móvel usando Kotlin com Retrofit e OkHttp. Em cada requisição GET, o cliente salva o ETag da resposta, e na próxima requisição o envia no cabeçalho If-None-Match. Se o servidor retornar 304, os dados não são baixados novamente.
Configuração do cliente OkHttp com 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}"))
}
}
}
O cliente salva o ETag após uma resposta 200 bem-sucedida e o envia no cabeçalho If-None-Match na próxima requisição. Com uma resposta 304, o cliente sabe que a versão local está atualizada e não gasta tráfego para baixar novamente. Este padrão reduz os custos de rede do aplicativo móvel em 80–90% para recursos solicitados com frequência.
ETag é um mecanismo chave para otimizar a sincronização de aplicações móveis com APIs REST. Em um esquema de sincronização padrão, o cliente primeiro solicita uma lista de recursos com validação ETag — se nenhum recurso mudou, o servidor retorna 304 e o cliente completa a sincronização. Se houver alterações, o servidor retorna apenas os recursos modificados. Esta abordagem é chamada de sincronização delta e é criticamente importante para dispositivos móveis com tráfego limitado.
Em cenários de bloqueio otimista, o ETag é usado para prevenir conflitos Lost Update. Quando um cliente envia uma requisição PUT para atualizar um recurso, ele inclui o cabeçalho If-Match: “etag”. Se o ETag não coincidir (outro cliente já modificou o recurso), o servidor responde com 412 Precondition Failed, e o cliente deve obter novamente a versão atual e tentar a modificação novamente. Esta abordagem garante consistência de dados sem bloqueios no nível do banco de dados.
Para sistemas distribuídos com modo offline, o ETag é usado em combinação com Resolução de Conflitos. O cliente sincroniza obtendo ETags atuais para todos os recursos. Ao enviar alterações, o servidor verifica If-Match — se o ETag não coincidir, um conflito é registrado e resolvido de acordo com a estratégia escolhida (LWW, Merge). De acordo com o Postman API Report (2025), 67% das APIs REST de produção para aplicações móveis usam ETag como mecanismo principal de validação de versões.
Perguntas frequentes
ETag é um cabeçalho de resposta HTTP contendo um identificador único de versão do recurso. O cliente o usa para requisições condicionais: se o recurso não mudou, o servidor retorna 304 Not Modified sem corpo de resposta, economizando tráfego.
ETag usa um hash de conteúdo para comparação precisa. Last-Modified é baseado na data de modificação com precisão de segundo. ETag é mais confiável para detectar mudanças reais e suporta bloqueio otimista via If-Match.
ETags fortes (sem prefixo) distinguem recursos byte a byte. ETags fracos (com prefixo W/) permitem equivalência semântica. Os fortes são necessários para requisições Range, os fracos para conteúdo gerado dinamicamente.
ETag reduz o tráfego em 80–90%: o cliente verifica a atualidade de todos os recursos via If-None-Match, baixando apenas os modificados. Sem ETag, o cliente baixaria dados completos em cada sincronização, desperdiçando tráfego e bateria.
O servidor calcula um ETag como um hash (MD5, SHA-256) do conteúdo da resposta ou usa um número de versão do registro no banco de dados. Em Spring Boot, a anotação @Cacheable com etag = true é suficiente. Em Express.js, o middleware etag está habilitado por padrão.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também