Home / Software / Requisições HTTP: como funcionam, estrutura e guia completo para desenvolvedores

Requisições HTTP: como funcionam, estrutura e guia completo para desenvolvedores

Requisições HTTP

Toda vez que você digita um endereço no navegador e pressiona Enter, uma série de eventos acontece em milissegundos: seu computador monta uma mensagem estruturada, envia pela internet para um servidor do outro lado do mundo, esse servidor processa a mensagem, prepara uma resposta e manda de volta. Você vê a página carregar. O protocolo que torna tudo isso possível — de forma padronizada, eficiente e compreensível por qualquer sistema — chama-se HTTP.

HTTP (HyperText Transfer Protocol) é o protocolo que sustenta a web. Toda página que você acessa, toda API que você consome, todo formulário que você envia passa por uma requisição HTTP. Entender como esse protocolo funciona não é apenas conhecimento teórico — é a base para depurar problemas de rede, otimizar performance, projetar APIs melhores e desenvolver aplicações mais robustas.

Neste guia, você vai entender o modelo Request-Response que define o HTTP, conhecer cada componente de uma requisição (método, URL, cabeçalhos e corpo), dominar os métodos mais usados e quando aplicar cada um, ver exemplos reais e comentados de requisições GET e POST, aprender sobre cabeçalhos HTTP e suas funções práticas, e descobrir as ferramentas que todo desenvolvedor usa para trabalhar com HTTP no dia a dia.

O que é HTTP e como ele opera?

HTTP significa HyperText Transfer Protocol — Protocolo de Transferência de Hipertexto. Criado por Tim Berners-Lee no início dos anos 1990, o protocolo define as regras de comunicação entre clientes (navegadores, aplicativos móveis, ferramentas de linha de comando) e servidores web.

O modelo fundamental do HTTP é simples: Request-Response (requisição-resposta). O cliente envia uma requisição; o servidor processa e retorna uma resposta. Esse ciclo, que parece trivial descrito assim, acontece dezenas de vezes por segundo em aplicações modernas — cada imagem, cada script, cada chamada de API gera sua própria requisição independente.

HTTP opera sobre TCP/IP, o protocolo de transporte da internet. Isso significa que HTTP não precisa se preocupar com a entrega confiável dos dados — o TCP cuida disso. O HTTP define o que é enviado e como é estruturado; o TCP garante que chegue.

A versão mais adotada atualmente é o HTTP/1.1, que permaneceu como padrão por décadas. HTTP/2 introduziu multiplexação (múltiplas requisições simultâneas sobre uma única conexão) e compressão de cabeçalhos. HTTP/3, mais recente, opera sobre QUIC em vez de TCP, reduzindo latência em conexões instáveis. Para desenvolvedores web, entender HTTP/1.1 em profundidade fornece a base para compreender as versões seguintes.

💡 Dica: HTTP é um protocolo sem estado (stateless) — cada requisição é independente e o servidor não guarda memória da requisição anterior. Isso simplifica a escalabilidade (qualquer servidor pode responder qualquer requisição), mas exige que aplicações que precisam de estado — como sessões de login — gerenciem esse estado explicitamente via cookies, tokens JWT ou sessões de servidor.

A estrutura de uma requisição HTTP

Uma requisição HTTP tem quatro componentes principais: método, URL, cabeçalhos e corpo. Cada um carrega uma categoria específica de informação que o servidor usa para processar a requisição corretamente.

Método (ou verbo) HTTP

O método define a ação que o cliente quer realizar sobre o recurso identificado pela URL. Os métodos são análogos a verbos — GET significa “me dê”, POST significa “receba isto”, DELETE significa “remova aquilo”.

A escolha do método correto não é apenas semântica — é parte do contrato que a API estabelece com seus consumidores. Usar POST para buscar dados, por exemplo, quebra o princípio de que buscas devem ser idempotentes e armazenáveis em cache.

URL (Uniform Resource Locator)

A URL identifica o recurso específico sobre o qual o cliente quer agir. Em https://api.exemplo.com/users/42/orders, cada segmento carrega significado:

  • https:// — protocolo (HTTPS é HTTP com criptografia TLS)
  • api.exemplo.com — o host (qual servidor recebe a requisição)
  • /users/42/orders — o path (qual recurso no servidor)

APIs RESTful bem projetadas usam paths que comunicam hierarquias de recursos. /users/42/orders deixa imediatamente claro que estamos acessando os pedidos do usuário com ID 42 — sem precisar ler documentação.

Cabeçalhos HTTP

Cabeçalhos são pares de chave-valor que transportam metadados sobre a requisição. Eles não fazem parte do recurso sendo solicitado — informam ao servidor como processar a requisição e ao cliente como interpretar a resposta.

Cabeçalhos críticos em requisições:

  • Content-Type: informa o formato dos dados no corpo da requisição. application/json indica JSON; multipart/form-data indica upload de arquivo; application/x-www-form-urlencoded indica formulário HTML padrão.
  • Accept: comunica ao servidor quais formatos de resposta o cliente suporta. O servidor usa essa informação para negociar o formato da resposta (content negotiation).
  • Authorization: transporta credenciais de autenticação. Tokens JWT geralmente aparecem aqui no formato Bearer <token>; API keys podem aparecer como ApiKey <chave>.
  • User-Agent: identifica o cliente que faz a requisição — qual navegador, qual versão, qual sistema operacional. Servidores podem usar essa informação para adaptar respostas a diferentes clientes.
  • Cookie: transmite cookies armazenados pelo cliente para o servidor, permitindo que sessões e preferências persisitam entre requisições.

Corpo da requisição (Body)

O corpo transporta dados do cliente para o servidor. Não está presente em todas as requisições — GET e DELETE tipicamente não têm corpo, pois o recurso é identificado completamente pela URL. POST, PUT e PATCH quase sempre têm corpo.

O conteúdo do corpo pode ser:

  • JSON: o formato mais comum em APIs modernas. Estruturado, legível por humanos e fácil de processar por praticamente qualquer linguagem.
  • Formulário URL-encoded: formato padrão de formulários HTML. Pares de chave-valor codificados para transmissão via URL.
  • Multipart/form-data: usado quando o formulário inclui upload de arquivos. Divide o corpo em partes, cada uma com seu próprio Content-Type.
  • XML: comum em sistemas legados e integrações corporativas.
  • Binário: para uploads de imagens, vídeos e outros arquivos.

⚠️ Atenção: o cliente e o servidor precisam concordar sobre o formato do corpo. O cabeçalho Content-Type declara o formato dos dados enviados; o servidor usa essa declaração para saber como deserializar o corpo. Enviar JSON sem o Content-Type: application/json correto frequentemente resulta em erros de parsing no servidor.

Os métodos HTTP: o vocabulário das ações

HTTP define vários métodos, mas quatro dominam o uso cotidiano em APIs e aplicações web:

GET — Recuperar dados

GET solicita a representação de um recurso. É o método mais comum — toda vez que você digita uma URL no navegador, o navegador envia um GET. Algumas propriedades fundamentais do GET:

Idempotente: múltiplas requisições GET ao mesmo recurso produzem o mesmo resultado. Isso significa que GET pode ser repetido com segurança.

Sem efeitos colaterais: GET não deve alterar o estado do servidor. Uma requisição GET a /users/42 deve retornar os dados do usuário, nunca modificá-los ou deletá-los.

Cacheável: por ser idempotente e sem efeitos colaterais, respostas GET podem ser armazenadas em cache por browsers, proxies e CDNs. Isso é uma das principais alavancas de performance em aplicações web.

Sem corpo: GET não tem corpo de requisição. Dados adicionais para filtrar ou paginar resultados vão nos query parameters da URL: /users?role=admin&page=2.

POST — Criar e enviar dados

POST submete dados ao servidor para processamento, geralmente para criar um novo recurso. Um POST a /users com dados de um novo usuário no corpo cria esse usuário no servidor.

POST não é idempotente — múltiplas requisições POST iguais geralmente criam múltiplos recursos. Isso é importante ao lidar com retry automático de requisições: retentar um POST em caso de falha pode criar duplicatas.

Além de criação de recursos, POST é usado para operações que não se encaixam em outros métodos: autenticação (POST /auth/login), processamento de dados (POST /invoices/123/send), operações que alteram estado de formas complexas.

PUT — Substituir um recurso completo

PUT atualiza um recurso existente ou cria um novo em uma URL específica. A diferença crucial em relação ao POST: PUT é idempotente. Enviar o mesmo PUT múltiplas vezes produz o mesmo resultado — o recurso fica no mesmo estado após a primeira e a décima chamada.

PUT substitui o recurso completamente. Um PUT a /users/42 com dados parciais pode apagar campos que não foram incluídos na requisição, dependendo da implementação do servidor. Para atualizações parciais, PATCH é mais adequado.

DELETE — Remover um recurso

DELETE solicita a remoção do recurso identificado pela URL. Como PUT, DELETE também é idempotente — deletar um recurso que já foi deletado deve retornar sucesso (ou um erro que indica “não existe mais”, não um erro de falha de operação).

DELETE geralmente não tem corpo, mas alguns sistemas usam o corpo para passar confirmação ou metadados da operação de remoção.

PATCH — Atualizar parcialmente

PATCH atualiza parcialmente um recurso — apenas os campos enviados no corpo são modificados, os demais permanecem inalterados. É a escolha mais adequada quando o cliente quer modificar apenas o email de um usuário sem precisar enviar todos os outros dados do usuário no corpo.

A distinção entre PUT e PATCH é importante para a clareza do contrato da API: PUT diz “substitua o recurso por isto”; PATCH diz “aplique estas mudanças ao recurso existente”.

Como uma requisição HTTP percorre a rede?

1. O cliente monta a requisição

O processo começa quando o cliente — um navegador, um aplicativo mobile ou uma ferramenta como curl — prepara a requisição. Isso inclui escolher o método, construir a URL, adicionar os cabeçalhos necessários e, se aplicável, serializar os dados para o corpo.

2. Resolução DNS

Antes de enviar qualquer dado, o cliente precisa descobrir o endereço IP do servidor identificado pelo hostname na URL. O sistema DNS (Domain Name System) faz essa resolução — api.exemplo.com se torna algo como 203.0.113.42. O resultado fica em cache no sistema operacional e no resolver DNS para evitar essa resolução em cada requisição.

3. Estabelecimento da conexão TCP (e TLS para HTTPS)

Com o IP do servidor em mãos, o cliente estabelece uma conexão TCP (o famoso “three-way handshake” — SYN, SYN-ACK, ACK). Para HTTPS, adiciona-se o handshake TLS, que negocia criptografia e verifica o certificado do servidor. Esse processo adiciona latência — é uma das razões pelas quais HTTP/2 e HTTP/3 priorizam o reuso de conexões.

4. Envio da requisição

Com a conexão estabelecida, o cliente transmite a requisição para o servidor. A mensagem segue a estrutura definida pelo protocolo: linha de requisição (método e URL), cabeçalhos e, separado por uma linha em branco, o corpo.

5. Processamento no servidor

O servidor recebe a requisição, interpreta o método e a URL, localiza o recurso ou o handler correspondente, e executa a lógica necessária. Isso pode envolver consultas a banco de dados, chamadas a serviços externos, transformações de dados e validações.

6. Geração e envio da resposta

O servidor prepara a resposta com um código de status (200 OK, 404 Not Found, 500 Internal Server Error), cabeçalhos de resposta e o corpo com os dados solicitados. A resposta percorre o caminho de volta ao cliente.

7. O cliente processa a resposta

O navegador ou aplicativo recebe a resposta, interpreta o código de status e os cabeçalhos, e processa o corpo. Um navegador renderiza HTML; um aplicativo mobile deserializa JSON e atualiza a UI; um script de automação lê os dados e os processa.

Todo esse ciclo, do request ao processamento da resposta, frequentemente acontece em menos de 100 milissegundos para servidores geograficamente próximos.

Exemplos práticos e comentados

Requisição GET com autenticação

GET /api/v1/users/42/orders?status=pending&page=1 HTTP/1.1

Host: api.exemplo.com.br
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MiJ9.abc123
User-Agent: MeuApp/2.1 (Android 14)

Análise:

  • GET — buscando dados, sem efeitos colaterais
  • /api/v1/users/42/orders — pedidos do usuário 42, versionamento da API via URL
  • ?status=pending&page=1 — filtros via query parameters, sem alterar o path do recurso
  • Accept: application/json — o cliente prefere resposta em JSON
  • Authorization: Bearer <token> — autenticação via JWT no header padrão
  • User-Agent — identifica o aplicativo e versão do SO para logging e analytics

Requisição POST com JSON

POST /api/v1/orders HTTP/1.1

Host: api.exemplo.com.br
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MiJ9.abc123
Accept: application/json
Idempotency-Key: 7f8a9b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c

{
  "items": [
    { "product_id": "prod_789", "quantity": 2 },
    { "product_id": "prod_321", "quantity": 1 }
  ],
  "shipping_address_id": "addr_456",
  "payment_method": "credit_card_ending_4242"
}

Análise:

  • POST — criando um novo pedido
  • Content-Type: application/json — informa que o corpo é JSON; o servidor usa isso para deserializar corretamente
  • Idempotency-Key — cabeçalho customizado que permite ao servidor detectar e descartar requisições duplicadas em caso de retry; essencial em operações financeiras
  • Corpo estruturado em JSON com os dados do pedido

Requisição PATCH para atualização parcial

PATCH /api/v1/users/42 HTTP/1.1

Host: api.exemplo.com.br
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MiJ9.abc123

{
  "email": "novo.email@exemplo.com.br"
}

Análise:

  • PATCH em vez de PUT — apenas o email será atualizado; todos os outros campos do usuário permanecem inalterados
  • O servidor aplica apenas o campo recebido — ao contrário do PUT, que substituiria o recurso inteiro

Cabeçalhos HTTP mais importantes na prática

Além dos cabeçalhos de requisição vistos acima, cabeçalhos de resposta carregam informações igualmente importantes:

Content-Type (resposta): informa o formato dos dados no corpo da resposta. O cliente usa isso para saber como processar o que recebeu.

Cache-Control: define regras de cache para a resposta. max-age=3600 permite que a resposta seja armazenada por uma hora; no-store impede qualquer cache; must-revalidate exige que o cache consulte o servidor antes de usar a versão armazenada.

ETag: um identificador único da versão atual de um recurso. Clientes enviam o ETag em requisições subsequentes via If-None-Match; se o recurso não mudou, o servidor retorna 304 Not Modified sem corpo, economizando largura de banda.

Location: após um POST bem-sucedido que cria um recurso, o servidor inclui a URL do novo recurso nesse cabeçalho. Convenção REST: POST /users bem-sucedido retorna 201 Created com Location: /users/42.

Retry-After: aparece em respostas 429 Too Many Requests e 503 Service Unavailable, indicando ao cliente quantos segundos esperar antes de tentar novamente.

CORS (Cross-Origin Resource Sharing): conjunto de cabeçalhos (Access-Control-Allow-Origin, Access-Control-Allow-Methods, etc.) que controlam quais origens podem fazer requisições à API. Essencial para APIs consumidas por aplicações web rodando em domínios diferentes.

Códigos de status HTTP: a linguagem dos resultados

Códigos de status comunicam o resultado de cada requisição de forma padronizada:

2xx — Sucesso:

  • 200 OK — a requisição foi bem-sucedida e a resposta contém o resultado
  • 201 Created — um novo recurso foi criado com sucesso
  • 204 No Content — sucesso, mas sem corpo na resposta (comum em DELETE)

3xx — Redirecionamentos:

  • 301 Moved Permanently — o recurso mudou de URL definitivamente; futuras requisições devem usar a nova URL
  • 304 Not Modified — o recurso não mudou desde a última vez que foi solicitado; o cliente pode usar a versão em cache

4xx — Erros do Cliente:

  • 400 Bad Request — a requisição está malformada ou inválida
  • 401 Unauthorized — credenciais ausentes ou inválidas; o cliente precisa se autenticar
  • 403 Forbidden — autenticado, mas sem permissão para o recurso
  • 404 Not Found — o recurso não existe nesse servidor
  • 422 Unprocessable Entity — a requisição está sintaticamente correta, mas semanticamente inválida (validação de negócio falhou)
  • 429 Too Many Requests — limite de taxa excedido

5xx — Erros do Servidor:

  • 500 Internal Server Error — erro inesperado no servidor
  • 502 Bad Gateway — o servidor intermediário recebeu uma resposta inválida do servidor de origem
  • 503 Service Unavailable — o servidor está temporariamente indisponível (manutenção ou sobrecarga)

💡 Dica: APIs que retornam 200 OK para tudo — incluindo erros — obrigam os consumidores a inspecionar o corpo de cada resposta para descobrir se a operação teve sucesso. Usar os códigos de status corretos é parte do contrato da API e melhora significativamente a experiência de desenvolvedores que a consomem.

Ferramentas para trabalhar com requisições HTTP

Postman: plataforma completa para explorar, testar e documentar APIs. Permite criar coleções de requisições organizadas, configurar ambientes (desenvolvimento, staging, produção), escrever testes automatizados que rodam após cada requisição e gerar documentação interativa.

Insomnia: alternativa ao Postman com interface mais limpa e suporte nativo a GraphQL. Excelente para times que preferem menos overhead de configuração.

curl: ferramenta de linha de comando que envia requisições HTTP a partir do terminal. Onipresente em sistemas Unix/Linux e essencial para automação, scripts e debugging em servidores sem interface gráfica.

# Exemplo de GET com curl
curl -X GET "https://api.exemplo.com.br/users/42" \
  -H "Authorization: Bearer seu-token-aqui" \
  -H "Accept: application/json"


# Exemplo de POST com JSON
curl -X POST "https://api.exemplo.com.br/users" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer seu-token-aqui" \
  -d '{"name": "Maria Silva", "email": "maria@exemplo.com.br"}'

HTTPBin: serviço online que retorna exatamente o que recebeu — útil para inspecionar como uma requisição chega ao servidor. httpbin.org/get retorna os cabeçalhos e parâmetros da requisição GET que você enviou, em JSON.

Browser DevTools: a aba Network do Chrome, Firefox e Safari mostra todas as requisições HTTP feitas pela página em tempo real, com detalhes completos de cabeçalhos, corpo, timing e tamanho de resposta. Ferramenta de debugging indispensável para desenvolvimento front-end.

Wireshark: para debugging de nível mais baixo, Wireshark captura e analisa pacotes de rede em tempo real. Útil quando você precisa ver exatamente o que trafega na rede, não apenas o que as ferramentas de alto nível mostram.

Perguntas frequentes sobre Requisições HTTP

Qual a diferença entre HTTP e HTTPS?


HTTP e HTTPS usam o mesmo protocolo de comunicação — a diferença é que HTTPS adiciona uma camada de criptografia TLS (Transport Layer Security) entre o HTTP e o TCP. Isso garante três coisas: os dados trafegam criptografados (confidencialidade), o cliente pode verificar a identidade do servidor pelo certificado digital (autenticação), e os dados não podem ser alterados em trânsito sem que seja detectado (integridade). Hoje, HTTPS é obrigatório para qualquer site que lida com dados dos usuários — browsers modernos mostram alertas de segurança para sites HTTP.

Quando usar POST vs PUT vs PATCH?


Use POST para criar recursos novos quando o servidor define a URL do recurso criado (POST /users cria um usuário e o servidor escolhe o ID). Use PUT para substituir completamente um recurso em uma URL específica (PUT /users/42 substitui o usuário 42 com os dados enviados). Use PATCH para atualizar parcialmente um recurso existente, modificando apenas os campos enviados sem afetar os demais. A distinção prática mais importante: PUT é idempotente (múltiplas chamadas produzem o mesmo resultado), POST geralmente não é.

O que são query parameters e quando usá-los?


Query parameters são pares de chave-valor adicionados à URL após o símbolo ?, separados por & — como em /users?role=admin&page=2&limit=20. Servem para filtrar, paginar, ordenar ou modificar a consulta sem alterar o recurso identificado pelo path. A convenção REST é: use o path para identificar o recurso (/users/42); use query parameters para modificar como aquele recurso é retornado (filtros, paginação, campos específicos). Dados que modificam o estado do servidor nunca devem ir em query parameters — pertencem ao corpo da requisição.

O que causa o erro CORS e como resolvê-lo?


CORS (Cross-Origin Resource Sharing) é um mecanismo de segurança do browser que bloqueia requisições de uma origem (domínio + protocolo + porta) para outra diferente por padrão. Quando seu front-end em app.exemplo.com tenta fazer uma requisição para api.exemplo.com, o browser primeiro envia uma “preflight request” (OPTIONS) perguntando se a API permite isso. A API precisa responder com cabeçalhos Access-Control-Allow-Origin, Access-Control-Allow-Methods e outros, autorizando a origem específica. Erros CORS são resolvidos no servidor (configurando esses cabeçalhos), não no front-end. Ferramentas como curl e Postman não sofrem restrições CORS — elas só afetam browsers.

Como funciona o cache em requisições HTTP?


Respostas HTTP podem incluir cabeçalhos que controlam como clientes e proxies as armazenam. Cache-Control: max-age=3600 permite armazenar a resposta por uma hora. ETag identifica a versão atual do recurso — em requisições subsequentes, o cliente envia o ETag via If-None-Match; se o recurso não mudou, o servidor responde 304 Not Modified sem corpo, economizando tempo e largura de banda. Cache-Control: no-store desabilita o cache completamente. Respostas com dados sensíveis ou que mudam com frequência devem usar no-store ou no-cache para garantir que os dados mostrados ao usuário sejam sempre atuais.

Conclusão

Requisições HTTP são a gramática da web — a estrutura que define como sistemas digitais se comunicam entre si. Entender essa gramática em profundidade permite depurar problemas que seriam opacos sem esse conhecimento, projetar APIs que seguem convenções que outros desenvolvedores reconhecem imediatamente, e otimizar a performance de aplicações que dependem de comunicação eficiente entre cliente e servidor.

Três pontos centrais para levar desta leitura: métodos HTTP não são arbitrários — cada um carrega semântica específica (idempotência, efeitos colaterais, cacheabilidade) que define como o método deve ser usado; cabeçalhos são parte integral da requisição, não detalhes secundários — Content-Type, Authorization e Cache-Control definem comportamentos críticos; e códigos de status corretos fazem parte do contrato da API, não são detalhes de implementação opcionais.

Para praticar: abra o DevTools do navegador, navegue para qualquer site e observe as requisições na aba Network. Veja os métodos, os cabeçalhos e os códigos de status em tempo real. Depois, use curl ou Postman para fazer requisições a uma API pública — as mesmas que você observou acontecendo automaticamente. A fluência em HTTP vem com a prática de ler e escrever requisições diariamente.

Deixe um Comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *