Conditional GET: o que é, o mecanismo de requisição condicional

Autor: IT Sectr Publicado: 2026-06-14 Tempo de leitura: 7 min

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 HTTP com cabeçalhos If-None-Match ou If-Modified-Since para verificar a relevância do cache.
  • 304 Not Modified — uma resposta do servidor indicando que o recurso não foi alterado. Nenhum corpo de resposta é enviado, economizando tráfego.
  • If-None-Match — um cabeçalho com um ETag (hash de versão), fornecendo validação precisa no nível do conteúdo do recurso.
  • If-Modified-Since — um cabeçalho com a data da última modificação, mais simples de implementar, mas menos preciso (resolução de 1 segundo).
  • Eficiência — Conditional GET reduz o volume de dados durante a sincronização em 80–95% para recursos não modificados.

O que é Conditional GET em HTTP?

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.

Como funciona uma requisição GET condicional

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:

kotlin
// 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.

Conditional GET vs GET normal

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âmetroGET normalConditional GET
Tráfego (sem alterações)Resposta completaApenas cabeçalhos (~200 bytes)
LatênciaDownload completoMilissegundos (304)
Carga do servidorGeração + transferênciaApenas verificação de ETag
Complexidade de implementaçãoMínimaRequer armazenamento de ETag
Eficiência para dados grandesBaixaAlta

Exemplos de implementação em Kotlin

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:

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.

Uso de Conditional GET no desenvolvimento móvel

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

O que é uma requisição Conditional GET?

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.

Como o Conditional GET difere de uma requisição normal?

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.

Como usar Conditional GET para cache?

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.

Como o Conditional GET ajuda a economizar tráfego?

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.

O Conditional GET pode ser usado para sincronização?

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

  • Conditional GET — um mecanismo HTTP para verificar a relevância de recursos em cache através dos cabeçalhos condicionais If-None-Match e If-Modified-Since.
  • 304 Not Modified — uma resposta do servidor indicando que o recurso não foi alterado. O corpo da resposta não é transmitido, economizando tráfego e tempo de carregamento.
  • ETag vs Last-Modified — ETag é mais preciso (hash de conteúdo), Last-Modified é mais simples (data). Recomenda-se combinar ambos para máxima eficiência.
  • Economia de tráfego — para recursos não modificados, o Conditional GET reduz o volume de dados transmitidos em 70–95% dependendo do tamanho do recurso.
  • Aplicações — mecanismo de sincronização padrão no Twitter, Instagram, Telegram e na maioria das APIs REST modernas.
  • Integração — no lado do cliente, é necessário armazenamento de ETag em um banco de dados local; no lado do servidor, geração e comparação de ETag em cada requisição.
  • Recomendação — implemente Conditional GET para todos os endpoints GET em sua API móvel. É a otimização mais barata com o maior impacto para os usuários.

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.

Discutir o projeto

Leia também