🌐
HTTP do zero: request, response, status, headers, cookies
⏱ 14 min de leitura·+70 XP
Pré-requisitos (0/1)0%
- ⬜🐙 GitHub profissional: PR, review, issues, Actions básico(Fundamentos Técnicos)
Recomendamos completar os pré-requisitos antes de seguir, mas nada te impede de continuar.
HTTP (HyperText Transfer Protocol) é o protocolo que move a web inteira. APIs REST, webhooks, browsers, apps mobile — tudo fala HTTP. Entender sua estrutura real não é opcional para quem desenvolve software moderno.
Anatomia de uma request e response HTTP
# Request HTTP/1.1 completa (o que vai pelo fio):
GET /api/users/42 HTTP/1.1
Host: api.exemplo.com
Accept: application/json
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
User-Agent: curl/8.4.0
Connection: keep-alive
# Request POST com body:
POST /api/users HTTP/1.1
Host: api.exemplo.com
Content-Type: application/json
Content-Length: 52
Authorization: Bearer eyJhbGci...
{"name": "Fernando", "email": "f@exemplo.com"}
# Response HTTP/1.1 completa:
HTTP/1.1 201 Created
Content-Type: application/json
Content-Length: 89
Location: /api/users/43
X-Request-Id: abc-123-def
Cache-Control: no-store
Date: Thu, 17 Apr 2026 10:00:00 GMT
{"id": 43, "name": "Fernando", "email": "f@exemplo.com", "created_at": "..."}Toda request tem: método + path + versão na primeira linha, headers (um por linha, formato Nome: Valor), linha em branco, e opcionalmente um body. Response tem: versão + status code + reason phrase, headers, linha em branco, e o body da resposta.
Métodos HTTP: semântica importa
| Método | Semântica | Idempotente? | Tem body? |
|---|---|---|---|
| GET | Leitura — nunca modifica | Sim | Não (prática) |
| POST | Criação / ação não-idempotente | Não | Sim |
| PUT | Substituição completa do recurso | Sim | Sim |
| PATCH | Atualização parcial | Não necessariamente | Sim |
| DELETE | Remoção do recurso | Sim | Não (prática) |
| HEAD | Igual GET, mas sem body na response | Sim | Não |
| OPTIONS | Quais métodos são suportados? (CORS preflight) | Sim | Não |
# Idempotência na prática:
# PUT /users/42 com body completo → mesmo resultado toda vez = idempotente
# DELETE /users/42 → mesmo resultado (404 na 2ª vez, mas o estado final é igual)
# POST /orders → cria um novo pedido a cada chamada = NÃO idempotente
# Idempotency key para POST seguro (padrão stripe/paypal):
POST /api/payments
Idempotency-Key: client-generated-uuid-abc123
{"amount": 100, "currency": "BRL"}
# Servidor: se já processou esta key, retorna o resultado original sem processar novamenteStatus codes: o que cada faixa significa
| Faixa | Categoria | Exemplos importantes |
|---|---|---|
| 1xx | Informacional | 101 Switching Protocols (WebSocket upgrade) |
| 2xx | Sucesso | 200 OK, 201 Created, 204 No Content |
| 3xx | Redirecionamento | 301 Moved Permanently, 302 Found, 304 Not Modified |
| 4xx | Erro do cliente | 400 Bad Request, 401 Unauth, 403 Forbidden, 404 Not Found, 429 Too Many Requests |
| 5xx | Erro do servidor | 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable |
# Status codes que todo dev confunde: # 200 vs 201 vs 204: GET /users/42 → 200 OK + body POST /users → 201 Created + body + header Location: /users/43 DELETE /users/42 → 204 No Content (sem body) # 301 vs 302 vs 307 vs 308: # 301 Moved Permanently → browser e crawlers atualizam a URL (SEO redirect) # 302 Found → redirect temporário (crawlers não atualizam) # 307 Temporary Redirect → como 302, mas garante manter o método HTTP # 308 Permanent Redirect → como 301, mas garante manter o método HTTP # 400 vs 422: # 400 Bad Request → request malformada (JSON inválido, campos obrigatórios faltando) # 422 Unprocessable Entity → sintaxe OK, mas semanticamente inválido # (email formatado corretamente mas já cadastrado) # 401 vs 403: # 401 → não autenticado → mostre tela de login # 403 → autenticado mas sem permissão → mostre "acesso negado" # 429 Too Many Requests → rate limited # Boas APIs incluem: Retry-After: 60 (segundos para aguardar)
Headers: metadados que controlam tudo
# Headers de Autenticação Authorization: Bearer <JWT-token> Authorization: Basic <base64(user:pass)> X-API-Key: abc123 # padrão de APIs simples # Headers de Conteúdo Content-Type: application/json # formato do BODY enviado Content-Type: multipart/form-data # upload de arquivo Accept: application/json # formato que o cliente ACEITA na resposta Content-Length: 1234 # tamanho em bytes do body Content-Encoding: gzip # body está comprimido # Headers de Cache Cache-Control: no-cache # sempre revalida com o servidor Cache-Control: no-store # não cacheia (dados sensíveis) Cache-Control: max-age=3600 # cacheia por 1 hora Cache-Control: public, max-age=86400 # cacheia em CDN por 1 dia ETag: "abc123" # identifier da versão do recurso If-None-Match: "abc123" # request condicional → 304 se não mudou # Headers de Rate Limiting (de facto padrão) X-RateLimit-Limit: 1000 # total de requests permitidas X-RateLimit-Remaining: 999 # quanto sobra na janela atual X-RateLimit-Reset: 1713350400 # quando a janela reseta (Unix timestamp) Retry-After: 60 # segundos para aguardar (em 429) # Headers de Segurança (response) Strict-Transport-Security: max-age=31536000; includeSubDomains X-Content-Type-Options: nosniff X-Frame-Options: DENY Content-Security-Policy: default-src 'self'
CORS: por que o browser bloqueia, mas curl não
# CORS: Cross-Origin Resource Sharing
# Origin = protocolo + host + porta: https://app.com vs https://api.com = origens diferentes
# 1. PREFLIGHT (request OPTIONS automática do browser antes de POST/PUT/custom headers):
OPTIONS /api/users HTTP/1.1
Origin: https://app.meusite.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Authorization, Content-Type
# 2. Server responde ao preflight:
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.meusite.com # ou: * para qualquer origem
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Max-Age: 86400 # cacheia o preflight por 1 dia
# 3. Browser envia a request real
# Se Access-Control-Allow-Origin não incluir a origem → browser bloqueia
# Configuração em Express.js:
app.use(cors({
origin: ['https://app.meusite.com', 'https://admin.meusite.com'],
credentials: true, // necessário para enviar cookies cross-origin
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
}));
# CORS com credentials (cookies/auth headers cross-origin):
# Server: Access-Control-Allow-Credentials: true + Access-Control-Allow-Origin NÃO pode ser *
# Client: fetch(url, { credentials: 'include' })✅
Ferramentas para explorar HTTP:
curl -v (veja headers completos), httpie (syntax mais amigável), Postman/Insomnia (GUI), DevTools → Network (browser) → clique na request → Headers.💡
Próximo: DNS, TLS e certificados — o que acontece nos milissegundos antes do seu request HTTP chegar ao servidor.
🧩
Quiz rápido
3 perguntas · Acerte tudo e ganhe o badge 🎯 Gabarito
Próximos passos sugeridos
Continue lendo