- GraphQL tenta resolver o problema de requisições excessivas de dados, mas, na maioria dos ambientes empresariais, isso já foi resolvido de outras formas
- Em sistemas corporativos onde a arquitetura BFF (Backend for Frontend) já é comum, a principal vantagem do GraphQL diminui bastante
- Complexidade de implementação, perda de observabilidade, problemas de cache, limitações de ID e dificuldade no processamento de arquivos aumentam o custo em ambientes reais de produção
- REST é simples e rápido, e facilita o tratamento de erros e o onboarding, sendo mais eficiente em equipes grandes
- Em conclusão, o GraphQL é útil em situações específicas, mas uma escolha excessiva para a maioria das empresas
O problema que o GraphQL tenta resolver
- O principal objetivo do GraphQL é evitar overfetching (solicitação excessiva de dados desnecessários)
- O cliente solicita apenas os campos de que precisa, reduzindo a transferência de dados desnecessários
- Também tem a vantagem de não exigir mudanças no backend a cada nova necessidade da UI
- Porém, no mundo real, essa estrutura idealizada não se encaixa bem em uma realidade mais complexa
Overfetching já resolvido com BFF
- A maioria dos frontends corporativos usa uma camada BFF (Backend for Frontend)
- Ela combina dados conforme a necessidade da UI, integra várias chamadas downstream e esconde a complexidade do backend
- Um BFF baseado em REST já consegue retornar apenas os dados necessários, então a vantagem do GraphQL se torna redundante
- Se a camada GraphQL busca dados em APIs REST, o overfetching apenas desce um nível
- O GraphQL pode ser útil quando várias páginas compartilham o mesmo endpoint, mas
- o ganho acaba sendo aceitar mais configuração e manutenção para economizar apenas alguns kilobytes
Complexidade de implementação e queda de produtividade
- O GraphQL exige muito mais tempo e complexidade de implementação do que REST
- É preciso trabalho extra com schema, tipos, resolvers e definição de fontes de dados
- Também existe o custo de manter schema e cliente sincronizados
- O GraphQL otimiza o consumo (conveniência para o cliente), mas sacrifica a produção (velocidade de desenvolvimento no servidor)
- Em ambientes corporativos, velocidade de produção e simplicidade importam mais
Problemas de observabilidade e monitoramento
- O GraphQL tem um uso inconsistente de códigos de status HTTP
- Uma resposta 200 pode conter erros, o que dificulta distinguir sucesso e falha no monitoramento
- No REST, 2XX/4XX/5XX separam tudo de forma clara, então filtrar dashboards é mais intuitivo
- Ferramentas como Apollo permitem customização, mas isso traz configuração extra e carga mental adicional
- Na resposta a incidentes em produção, entender o problema é mais difícil e mais complexo do que com REST
Limites práticos do cache
- O normalized caching do Apollo é teoricamente poderoso, mas na prática é frágil e complexo
- Consultas que diferem em apenas um campo são tratadas separadamente e exigem ligação manual
- Fazer debug do cache vira um problema à parte
- Já no REST, basta armazenar em cache a resposta inteira, o que é mais estável e fácil de manter
O problema das restrições de campos de ID
- O Apollo assume que todo objeto tenha um campo id ou _id
- Muitas APIs corporativas não têm IDs únicos, ou não usam identificadores globais
- Para se adaptar, o BFF precisa adicionar lógica local de geração de IDs
- No fim, isso aumenta campos e lógica desnecessários, anulando o benefício de reduzir overfetching
Ineficiência em upload e download de arquivos
- O GraphQL é inadequado para lidar com dados binários
- Na prática, ele retorna uma URL de download e o arquivo é transferido por REST
- Incluir dados grandes, como PDFs, na resposta GraphQL causa queda de desempenho
- Com isso, o ideal de uma “API única” do GraphQL se desfaz
Onboarding e curva de aprendizado
- A maioria dos desenvolvedores tem muita experiência com REST, mas GraphQL exige aprendizado
- É preciso aprender novos conceitos como schema, resolvers, construção de queries, regras de cache e tratamento de erros
- Isso reduz a velocidade de onboarding da equipe
- O REST é uma abordagem “sem graça, mas altamente escalável”, o que o torna adequado para equipes grandes
Complexidade no tratamento de erros
- As respostas de erro do GraphQL são complexas, com campos nullable, partial data, array
errors e códigos de status estendidos
- Também é necessário rastrear qual resolver falhou
- No REST, basta separar em 400/500, o que torna o entendimento e o debug mais fáceis
Conclusão: GraphQL é uma tecnologia de nicho
- O GraphQL é uma ferramenta válida em situações específicas
- Mas, na maioria dos ambientes empresariais, o problema já foi resolvido com BFF e REST
- Os desafios principais não são overfetching, e sim observabilidade, confiabilidade e velocidade
- No fim, o GraphQL resolve um problema estreito enquanto cria uma complexidade mais ampla
- A conclusão é: “GraphQL não é ruim, mas, na maioria dos casos, não é necessário”
2 comentários
Pode ter prós e contras, mas projetar dados e controle de acesso no nível do schema, e ficar adicionando coisas na REST API toda vez que se acrescenta algo, ainda parece melhor do que depois acabar retornando tudo. Os pontos fracos são claros, mas os pontos fortes também são bem claros haha
Comentários do Hacker News
Não concordo com o texto que define o principal problema do GraphQL como overfetching
Para mim, as verdadeiras vantagens são: (a) impor um contrato rígido baseado em tipos e (b) tornar a evolução do schema muito mais fácil
Graças ao sistema de tipos, entrada e saída sempre seguem formatos definidos, e usar tipos escalares customizados (por exemplo, número de telefone, e-mail etc.) pode reduzir bastante bugs e problemas de segurança
Além disso, adicionar novos campos ou descontinuar campos existentes é padronizado, então a carga cognitiva para servidor e cliente é menor
Uso GraphQL por causa da composição e evolução da API. Especialmente em sistemas grandes com estrutura M:N, o fluxo “o cliente descreve o que precisa → o servidor compõe → os serviços de domínio resolvem” é muito mais fácil de manter no longo prazo
Com boa observability, isso vira uma base poderosa para acesso a dados
Outro ponto é como fica fácil reutilizar resolvers e federation. Em REST isso é bem mais trabalhoso
Protobuf também lida bem com evolução de schema
A verdadeira vantagem do GraphQL é poder compor dados de UI em pequenos pedaços
Como neste vídeo, se você usa fragment colocation, pode alterar componentes filhos sem impactar outras partes
Como as queries são geradas automaticamente com base nos fragments, o risco de quebrar outros componentes ao remover um campo também diminui
Se a escala for pequena ou velocidade de desenvolvimento não for algo importante, GraphQL pode até parecer um investimento excessivo
Colocation é um conceito realmente revolucionário, mas a Apollo quase nunca falou disso
A documentação do Relay ainda deixa a desejar, mas o conceito de Entrypoint é excelente
Mas a implementação do graphql-codegen tem baixa compatibilidade entre plugins, então tivemos que criar nossos próprios plugins
Falta consistência em todo o ecossistema
Dizer que overfetching é o problema central do GraphQL é exagero
Vejo GraphQL como uma ferramenta que trata, no nível do cliente, a impedance mismatch que o ORM resolve
Usá-lo sem tooling baseado em compilador como o Relay é um antipadrão
Hoje em dia, como a IA gera automaticamente a camada de dados, a necessidade de GraphQL parece estar diminuindo
A experiência de desenvolvimento (DevEx) é excelente, com coisas como selecionar um campo inexistente e ele ser gerado automaticamente
A lentidão da web moderna vem, em grande parte, de transferência excessiva de dados. Na prática, muitos apps operam com eficiência abaixo de 0,5%
Eu uso GraphQL desde 2016
Em essência, GraphQL é uma especificação de RPC. Ele é implementado como um mapa do servidor do tipo “Action(Args) → ResultType”
Em vez de vários endpoints como no REST, o GraphQL funciona com um único endpoint
/query, usando um mapa de resolversNo fim, é uma estrutura em que entrada e saída são definidas por tipos, como OpenAPI ou gRPC
A Apollo melhorou um pouco ao adicionar fragment masking, mas ainda assim a forma de pensar centrada em Relay continua importante
e o backend converte isso em uma única query SQL para processar tudo
Resolver só deveria ser usado excepcionalmente para dados que não podem ser buscados diretamente no banco
Quando eu liderava uma equipe no passado, o front-end queria GraphQL, então adotamos
No fim, cada página buscava todos os dados com uma única query gigantesca e, a cada alteração, reenviava o JSON blob inteiro
O app funcionava, mas depois a empresa fez um pivot e aquele código desapareceu
Na prática, muitos projetos em GraphQL parecem terminar assim, como uma implementação só de fachada
O fluxo de autenticação (auth) no GraphQL é um dos maiores desafios
Como os resolvers podem ser chamados em vários contextos diferentes, é preciso considerar todos os casos
A complexidade e o custo mental ficam tão altos que, no fim, você acaba bloqueando campos
Eu mesmo criei o graphql-autharoo, mas não foi suficiente
A maior parte das funcionalidades pode ser implementada de forma mais simples sem GraphQL
É preciso adicionar permissões detalhadas a cada recurso GraphQL, então a query só funciona depois que todos os recursos forem atualizados
O peso disso é tão grande que surgem comentários do tipo “é melhor refazer isso em REST”
Acho melhor usar um framework de servidor mais completo em vez de montar tudo manualmente
O GraphQL parece bom à primeira vista, mas na prática é uma tecnologia que fica difícil de manter com o passar do tempo
Como acontece com muitas tecnologias, isso acaba ensinando que uma roda continua sendo só uma roda
A vantagem do GraphQL é que, se você só adiciona campos ao schema, todos os clientes podem consultá-los imediatamente
Desaparecem os pedidos do front-end do tipo “adiciona esse campo também”, o que simplifica a colaboração
Além disso, também é fácil criar snapshots do schema para detectar mudanças em testes de integração
Achei isso mais consistente do que REST, mas é uma experiência pessoal
Como dá para encadear requisições de A até E, problemas de desempenho e o acoplamento entre front-end e estrutura de dados ficam mais graves
O React agora também usa por padrão SSR baseado em framework e server components
No fim, a direção parece ser a de TypeScript unificar cliente e servidor
Tenho curiosidade de saber como o GraphQL evita problemas de carga no banco ou queries ineficientes
Não seria possível que uma query maliciosa explodisse o estado interno?
Estou tentando GraphQL porque REST é entediante demais
Gosto da ideia de servidor e cliente poderem entrar em acordo sobre requisição e resposta em tempo de compilação
Seria bom se os blogs não ficassem só dizendo “isso é ruim”, mas também apresentassem tecnologias alternativas
As duas tecnologias resolvem muito bem o problema de contrato entre cliente e servidor