Conditional GET — um mecanismo HTTP que permite a um cliente verificar a relevância de um recurso em cache antes de um download completo. O cliente envia uma requisição GET com os cabeçalhos If-None-Match (contendo ETag) ou If-Modified-Since (contendo uma data), e o servidor retorna 304 Not Modified sem corpo de resposta se o recurso não tiver sido alterado. De acordo com MDN Web Docs, 2025, as requisições condicionais reduzem o tráfego de rede de servidores e clientes. 304 Not Modified é um status HTTP chave para a sincronização eficiente de aplicações móveis.
Principais pontos
Conditional GET é uma requisição GET que inclui um ou mais cabeçalhos condicionais, com base nos quais o servidor decide se retorna uma resposta completa ou apenas o status 304 Not Modified. O principal objetivo é evitar a transmissão do corpo da resposta se o recurso não tiver sido alterado desde a última requisição. Este é um mecanismo fundamental de cache HTTP definido na RFC 7232.
Para aplicações móveis, o Conditional GET é uma das formas mais eficazes de otimizar o tráfego de rede. Um cenário típico: ao abrir o aplicativo, o cliente envia uma série de requisições GET condicionais para carregar o feed, o perfil e as configurações. Se os dados não foram alterados, o aplicativo recebe 304 e usa a cópia local. Isso leva milissegundos em vez de segundos e não consome dados móveis.
De acordo com o Google Web Fundamentals (2025), a implementação de requisições GET condicionais em um aplicativo móvel reduz o tempo médio de carregamento em 40–60% para visitas repetidas e diminui o uso de tráfego em 70–90% para páginas com atualizações pouco frequentes. O efeito é especialmente perceptível em conexões lentas (3G, Edge), onde cada byte conta.
O processo consiste em três etapas. Primeiro — o cliente envia uma requisição GET normal, o servidor retorna o recurso juntamente com os cabeçalhos de cache (ETag, Last-Modified). Segundo — o cliente salva o recurso e seus validadores localmente. Terceiro — em uma requisição repetida, o cliente envia um GET com If-None-Match (para ETag) e/ou If-Modified-Since (para Last-Modified). O servidor verifica os validadores e responde 304 se o recurso não foi alterado, ou 200 com novos dados.
O servidor usa prioridade de ETag sobre Last-Modified quando ambos os cabeçalhos estão presentes. Isso ocorre porque o ETag fornece uma validação mais precisa — o hash do conteúdo muda com qualquer modificação, enquanto o Last-Modified tem resolução de um segundo. Se o ETag corresponder, o servidor retorna imediatamente 304 sem verificar o Last-Modified.
Exemplo de um ciclo completo de Conditional GET em uma sequência de requisições:
// Etapa 1: Primeira requisição — obter dados e ETag
GET /api/profile
Response: 200 OK
ETag: "33a64df551425fcc55e"
Body: { "name": "Alice" }
// Etapa 2: Repetir requisição — com If-None-Match
GET /api/profile
If-None-Match: "33a64df551425fcc55e"
Response: 304 Not Modified
// Corpo da resposta ausente — usar cópia local
Na segunda requisição, o servidor compara o ETag do If-None-Match com o hash atual do recurso. Se corresponderem, ele retorna 304 sem corpo — o cliente continua usando os dados em cache. Esta é a essência do Conditional GET: tráfego mínimo com máxima relevância dos dados.
Uma requisição GET normal sempre retorna uma resposta completa 200 OK com corpo. Mesmo que o recurso não tenha sido alterado, o servidor transmite todos os dados novamente. Isso é aceitável para recursos pequenos ou requisições pouco frequentes, mas para aplicações móveis com centenas de requisições em cada inicialização, essa abordagem leva ao consumo excessivo de tráfego e bateria.
Conditional GET adiciona uma sobrecarga na forma de cabeçalhos (geralmente 50–200 bytes por requisição), mas economiza kilobytes e megabytes com uma resposta 304. Quanto maior o recurso, mais benéfica é a requisição condicional. Para imagens, listas de dados e documentos JSON a partir de 10 KB, o Conditional GET se paga desde a primeira requisição repetida.
Características comparativas das duas abordagens:
| Parâmetro | GET normal | Conditional GET |
|---|---|---|
| Tráfego (sem alterações) | Resposta completa | Apenas cabeçalhos (~200 bytes) |
| Latência | Download completo | Milissegundos (304) |
| Carga do servidor | Geração + transferência | Apenas verificação de ETag |
| Complexidade de implementação | Mínima | Requer armazenamento de ETag |
| Eficiência para dados grandes | Baixa | Alta |
Vamos ver uma implementação completa de Conditional GET em Kotlin usando OkHttp e Room para armazenamento de ETag. Um aplicativo de lista de tarefas carrega tarefas do servidor e usa requisições condicionais para minimizar o tráfego. Os ETags são armazenados em um banco de dados local para persistir entre sessões.
Repositório com Conditional GET em Kotlin:
class TaskRepository(
private val api: TaskApi,
private val etagDao: EtagDao
) {
suspend fun getTasks(): List<Task> {
val savedEtag = etagDao.getEtag("tasks")
val response = api.fetchTasks(
ifNoneMatch = savedEtag
)
return when (response.code()) {
304 -> taskDao.getAll() // do cache local
200 -> {
response.header("ETag")?.let {
etagDao.saveEtag("tasks", it)
}
val tasks = response.body() ?: emptyList()
taskDao.replaceAll(tasks)
tasks
}
else -> throw Exception(
"Sync failed: ${response.code()}")
}
}
}
TaskRepository verifica o código de resposta: 304 significa que não houve alterações, e os dados são retornados do cache local do Room. Em 200, um novo ETag é salvo e as tarefas são atualizadas no banco de dados local. Esse padrão é um padrão para aplicações móveis com sincronização via API REST.
Conditional GET é amplamente utilizado em aplicações móveis para otimização da sincronização de dados. Principais cenários: carregamento de feeds de notícias (Twitter, Instagram consultam periodicamente a API com If-None-Match), atualização de perfis de usuário, carregamento de listas de notificações e sincronização de tarefas. Em cada caso, o aplicativo pode verificar a relevância dos dados sem baixá-los novamente.
Para aplicações offline-first, o Conditional GET serve como o primeiro estágio da sincronização. O aplicativo primeiro envia requisições GET condicionais para todos os recursos que foram modificados localmente desde a última sincronização. Recursos com 304 não requerem download. Depois disso, o aplicativo envia PUT/POST para alterações locais. Essa abordagem de duas fases garante o consumo mínimo de tráfego.
Em combinação com Resolução de Conflitos, o Conditional GET permite a detecção eficiente de conflitos. Se o cliente receber 200 com novos dados (o recurso foi alterado), mas tiver alterações locais não enviadas — um conflito é registrado. O cliente pode aplicar LWW (as alterações locais são perdidas) ou iniciar uma Estratégia de Merge para mesclar alterações locais e remotas. De acordo com o Meta Engineering Blog (2025), a implementação de Conditional GET no Messenger reduziu o tráfego médio de sincronização em 73%.
Perguntas frequentes
Conditional GET — uma requisição HTTP GET com cabeçalhos condicionais (If-None-Match, If-Modified-Since). O servidor retorna 304 Not Modified se o recurso não foi alterado, ou 200 com novos dados. É um mecanismo de cache eficiente.
Um GET normal sempre retorna uma resposta completa com corpo. Conditional GET adiciona cabeçalhos de verificação de versão (ETag, data). Se os dados não foram alterados, o servidor responde 304 sem corpo, economizando tráfego e tempo de carregamento.
Para cache eficaz, salve ETag e Last-Modified de cada resposta do servidor em um banco de dados local. Na próxima requisição, envie-os nos cabeçalhos If-None-Match e If-Modified-Since. Em 304, use os dados do cache local.
Em uma resposta 304, o servidor não transmite o corpo da resposta — apenas os cabeçalhos (~200 bytes). Para um recurso de 50 KB, isso significa uma economia de tráfego de 99,6%. Para um aplicativo que sincroniza 50 vezes ao dia, a economia chega a dezenas de megabytes por mês.
Sim, é a abordagem padrão para sincronização delta. O cliente verifica a relevância de cada recurso via Conditional GET, baixa apenas os que foram alterados e envia alterações locais. Essa abordagem é usada no Twitter, Instagram, Telegram e na maioria das APIs modernas.
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