System Design/02 - Componentes/Communication2 min
REST
- Que problema isso resolve?
- Quando usar / quando NÃO usar?
- Qual o principal trade-off?
- Como isso falha em produção?
Conceito
Estilo arquitetural baseado em recursos identificados por URL e manipulados pelos verbos do HTTP.
GET /pedidos listar
POST /pedidos criar
GET /pedidos/42 ler
PUT /pedidos/42 substituir
PATCH /pedidos/42 alterar parcialmente
DELETE /pedidos/42 remover
GET /pedidos/42/itens sub-recurso
As restrições que definem REST
| Restrição | Significa |
|---|---|
| Cliente-servidor | Separação de responsabilidades |
| Stateless | Toda requisição carrega seu contexto |
| Cacheável | A resposta declara se pode ser cacheada |
| Interface uniforme | Mesmas convenções para todo recurso |
| Camadas | Cliente não sabe se fala com proxy ou origem |
| HATEOAS | Respostas trazem links de navegação (raramente adotado) |
Convenções que a prática consolidou
- Substantivos no plural, não verbos:
/pedidos, não/getPedidos - Versionamento:
/v1/pedidosou headerAccept - Paginação por cursor (estável) em vez de offset (instável sob escrita)
- Filtro e ordenação por query string
- Erros com corpo estruturado, não só o status code
Trade-offs
| Ganha | Perde |
|---|---|
| Cache HTTP nativo | Over-fetching — vem mais campo que o necessário |
| Universal, sem SDK | Under-fetching — N requisições para montar uma tela |
| Ferramentas maduras | Sem contrato forte (sem OpenAPI) |
| Fácil de depurar | Verboso (JSON textual) |
Over-fetching e under-fetching são o motivo de GraphQL existir: uma tela que precisa de usuário, pedidos e endereços faz três chamadas e recebe muitos campos que não usa.
REST também é fraco para operações que não são CRUD. "Aprovar", "cancelar", "reprocessar" não são recursos — e as saídas (POST /pedidos/42/aprovacao, ou um campo de estado no PATCH) são convenções, não algo que o estilo resolva bem. Aí RPC é mais honesto.
O que REST tem de único e frequentemente decisivo: ele se encaixa na infraestrutura da web. Cache de borda, proxies, ETag, 304, rate limit por rota, observabilidade por status code — tudo funciona sem nada especial.
Exemplo prático
Uma tela de perfil que precisa de dados do usuário, seus últimos 10 pedidos e o endereço padrão:
GET /usuarios/42 → 40 campos, a tela usa 3
GET /usuarios/42/pedidos?limit=10
GET /enderecos/7
Três rodadas de rede e muito campo descartado. Num app móvel em rede ruim, isso é a diferença entre a tela abrir em 200 ms e em 900 ms.
As saídas dentro do REST: um endpoint composto (/usuarios/42/perfil-completo) — que quebra a uniformidade — ou Backends for Frontend, que assume a composição como responsabilidade de uma camada dedicada.
Relacionado
Parte de Communication · roadmap.sh/system-design