trilha

System Design/02 - Componentes/Communication2 min

GraphQL

Perguntas-guia
  • Que problema isso resolve?
  • Quando usar / quando NÃO usar?
  • Qual o principal trade-off?
  • Como isso falha em produção?

Conceito

Linguagem de consulta para APIs em que o cliente declara exatamente os campos que quer, num único endpoint.

query {
  usuario(id: 42) {
    nome
    pedidos(ultimos: 10) { id total
      itens { produto { nome } }
    }
  }
}

Uma requisição, exatamente os campos pedidos, em qualquer profundidade.

Peças

Peça Papel
Schema Contrato tipado — a fonte da verdade
Query Leitura
Mutation Escrita
Subscription Push via WebSocket
Resolver Função que resolve cada campo

Trade-offs

Ganha Perde
Acaba over/under-fetching Cache HTTP não funciona (tudo é POST /graphql)
Um endpoint, schema tipado N+1 nos resolvers
Evolução sem versionar Complexidade de servidor bem maior
Introspecção e tooling Query maliciosa pode derrubar o servidor

Os três problemas sérios, em ordem de importância prática:

Cache. Em REST, GET /pedidos/42 é cacheável por qualquer camada da web. Em GraphQL, tudo é POST com corpo variável — nenhuma CDN ou proxy consegue cachear. A saída é cache no cliente por normalização (Apollo, Relay) e persisted queries, que transformam a consulta num hash cacheável.

N+1. Um resolver de itens chamado para cada um dos 10 pedidos gera 10 consultas ao banco. É o Chatty IO em forma de resolver, e a solução padrão é DataLoader — agrupar as chamadas do mesmo tick numa consulta em lote.

Custo de query. Um cliente pode escrever uma consulta profundamente aninhada que faz o servidor executar milhares de resolvers. Defesas: limite de profundidade, análise de custo, timeout e allow-list de queries.

E o custo de observabilidade: com um endpoint só, métricas por status code e por rota deixam de significar algo — a instrumentação precisa ser por campo e por resolver.

Exemplo prático

O mesmo perfil de REST, que exigia três chamadas e trazia 40 campos para usar 3:

query { usuario(id: 42) {
  nome
  enderecoPadrao { rua cidade }
  pedidos(ultimos: 10) { id total }
} }

Uma rodada de rede, zero campo desperdiçado. Num app móvel, é a diferença mais visível que GraphQL entrega.

O que ele cobra em troca: os resolvers de enderecoPadrao e pedidos precisam de DataLoader para não virar N+1, e a resposta não será cacheada por nenhuma CDN. A escolha, portanto, não é "GraphQL é melhor" — é qual dos dois conjuntos de problemas custa menos no seu caso.

Relacionado


Parte de Communication · roadmap.sh/system-design

Buscar

Busca por título, seção e texto das notas