HTTP para o Backend
HTTP = Hypertext Transfer Protocol (Protocolo de Transferência de Hipertexto)
Obs: Toda vez que você ler a palavra "protocolo", saiba que é basicamente um conjunto de passos pré-definidos.
Stateless
- As requisições não guardam estado
- Cada requisição é tratada como algo totalmente novo
- O servidor não “lembra” automaticamente quem você é ou o que você fez antes
Obs: Por isso existem mecanismos extras, como: Cookies, Sessions, Tokens JWT e Local Storage.
Client-server model
O modelo Client–Server é a base da maior parte da internet moderna.
- Client - Faz as requisições
- Server - processa e responde.
Devemos lembrar que o http sozinho não “envia bits”, Ele depende do TCP.
O TCP é responsável por:
- conexão
- confiabilidade
- ordenação
- retransmissão
- controle de fluxo
- controle de congestionamento
Sem TCP, o HTTP teria que implementar tudo isso sozinho.
HTTP 1.1 (ainda presente)
- TCP
- Cada requisição abre uma nova conexão TCP
- Lento
- Sofre de Head-of-line blocking (um pacote de dados ou solicitação no início da fila atrasa todos os outros que vêm atrás)
- Formato de texto plano
HTTP 2 (dominante na web moderna)
- TCP
- Mais rápido
- Multiplexing (permite enviar múltiplas requisições (solicitações de arquivos) e receber várias respostas do servidor simultaneamente, usando uma única conexão TCP)
- Frames binários
- Compressão de headers (usa o algoritmo HPACK para realizar a compressão)
- Ainda sofre de Head-of-Line Blocking (mesmo com multiplexing se um pacote TCP se perde toda stream espera retransmissão)
HTTP 3 (adoção crescente)
- UDP
- QUIC implementa confiabilidade no user space
- Melhora multiplexação
- Reduz latência
- QUIC resolve o problema do Head-of-line blocking.
- QUIC suporta 0-RTT (Cliente pode enviar dados IMEDIATAMENTE ao reconectar.)
Anatomia
Exemplo:
GET /api/users HTTP/1.1
Host: example.com
User-Agent: Chrome/136
Accept: application/json
Authorization: Bearer abc123
{
"name": "Matheus"
}
Request Line
- método
- path
- versão HTTP
GET /api/users HTTP/1.1
Headers
- quem está enviando
- que tipo de dado aceita
- autenticação
- cache
- cookies
- compressão
- origem
- comportamento da conexão
Host: example.com
User-Agent: Chrome/136
Accept: application/json
Authorization: Bearer abc123
Body
- Corpo da requisição
- Os dados
- Normalmente um Json
{
"name": "Matheus"
}
Métodos
Os métodos/verbos HTTP definem a intenção da requisição.
| Método | Objetivo |
|---|---|
| GET | Buscar dados |
| POST | Criar algo |
| PUT | Substituir |
| PATCH | Atualizar parcialmente |
| DELETE | Remover |
| HEAD | Buscar apenas headers |
| OPTIONS | Descobrir capacidades |
| TRACE | Debug |
| CONNECT | Túnel/proxy |
CORS
CORS é um mecanismo HTTP que permite ao servidor informar ao navegador se uma aplicação web hospedada em uma origem tem permissão para acessar recursos de outra origem diferente (Cross-Origin)
Origin = scheme + host + port
https://example.com:443
Mesma origem vs Cross-Origin
Mesma origem
FRONT
https://app.com
API
https://app.com/api
A requisição vem da mesma origem.
Cross-Origin
FRONT
https://frontend.com
API
https://api.backend.com
Origens diferente, nesse caso a politica de CORS vai definir se autoriza a requisição, caso ele aceite, será adicionado ao header da resposta um:
Access-Control-Allow-Origin: https://frontend.com
Simple Requests vs Preflighted Requests
Simple Request
Com headers simples:
- Accept
- Content-Type simples
- etc.
Tipo um GET (nem sempre), o navegador envia diretamente.
Preflighted Requests
O browser faz preflight quando a request é considerada “potencialmente perigosa” ou “não simples”.
Exemplos:
- método PUT
- DELETE
- PATCH
- Authorization header
- Content-Type JSON
- headers customizados
Exemplo do DELETE:
FRONT
fetch("https://api.com/users", {
method: "DELETE",
headers: {
"Authorization": "Bearer abc"
}
})
O navegador NÃO envia isso imediatamente.
Primeiro faz:
OPTIONS Request (lembra? options = descobrir capacidades)
OPTIONS /users HTTP/1.1
Origin: https://frontend.com
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: Authorization
Isso é o Preflighted Requests
Navegador está perguntando:
Posso fazer:
- DELETE
- com Authorization header
- vindo dessa origin?
Resposta do servidor
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://frontend.com
Access-Control-Allow-Methods: GET, POST, DELETE
Access-Control-Allow-Headers: Authorization
Agora o browser permite a request real.
DELETE /users HTTP/1.1
Authorization: Bearer abc
Origin: https://frontend.com
Obs: CORS NÃO substitui:
- CSRF tokens
- autenticação
- autorização
Ele é apenas uma política do browser.
Status Code
1xx - Informação
2xx - Sucesso
3xx - Redirecionamento
4xx - Erro do cliente
5xx - Erro do servidor
HTTP Caching
Sim, HTTP usa caching e grande parte da velocidade da internet depende de cache.
*HTTP caching é distribuído:
Browser Cache
CDN Cache
Proxy Cache
Reverse Proxy
API Gateway
Service Worker
Caching HTTP é controlado principalmente por headers:
| Header | Função |
|---|---|
| Cache-Control | regras de cache |
| ETag | identificação de versão |
| Last-Modified | última modificação |
| Expires | expiração absoluta |
| If-None-Match | validação usando ETag |
| If-Modified-Since | validação temporal |
Cache-Control: max-age=60
Recurso pode ser reutilizado por 60 segundos.
Simulação usando o Etag
Primeira requisição:
GET /app.js HTTP/1.1
Host: app.com
Resposta:
HTTP/1.1 200 OK
Content-Type: application/javascript
Content-Length: 120000
Cache-Control: no-cache
ETag: "v1-abc123"
console.log("App carregado");
Agora o browser salva o arquivo app.js e salva o ETag v1-abc123
Segunda requisição:
GET /app.js HTTP/1.1
Host: app.com
If-None-Match: "v1-abc123"
If-None-Match?
O browser está perguntando: "O recurso ainda está na versão v1-abc123?"
Servidor verifica a Etag:
ETag: "v1-abc123"
Resposta:
HTTP/1.1 304 Not Modified
ETag: "v1-abc123"
Not modified = arquivo não foi alterado, ou seja, pode usar a versão em cache.
Fluxo visual:
Browser Server
│ │
│ GET /app.js │
│─────────────────────>│
│ │
│ 200 OK + ETag │
│<─────────────────────│
│ │
│ salva cache │
│ │
(segundo acesso)
│ GET + If-None-Match │
│─────────────────────>│
│ │
│ 304 Not Modified │
│<─────────────────────│
│ │
│ usa cache local │