Executando verificação de segurança...
6

[GraphQL ou Rest] Explorando o poder "desconhecido" do temido GraphQL

Introdução

Esses dias caí nessa pergunta do Reddit: Devs, quando usar GraphQL?

Para minha não surpresa, a maior parte das respostas diziam "nunca", e as justificativas eram: "muito complexo", "poucas vantagens"...

Ler essas respostas me ajudou a reforçar uma percepção que eu já tinha: os devs acham que GraphQL serve apenas para resolver o problema de under/overfetching e que quem usa quer apenas seguir uma "modinha'.

E como uso GraphQL em praticamente todos os meus projetos pessoais/profissionais há pelo menos 5 anos e não consigo mais viver sem, resolvi trazer um post aqui no TabNews pra explorarmos alguns motivos pelo qual acredito que você provavelmente deveria dar uma chance a ele.

O poder do GraphQL

DISCLAIMER: Muito do poder e dos benefícios que trarei aqui estão vinculados a linguagem que uso: Typescript. Se você trabalha em outra linguagem, talvez você possa ser o responsável por trazer ao mundo as ferramentas que faltam.

Vamos começar direto pelo que considero ser o maior benefício do uso do GraphQL.

Benefício 1: A auto-documentação nativa das operações

Se você trabalha com REST, você cria suas rotas e elas ficam nativamente "escondidas". O cliente da API não sabe quantas ou quais rotas existem, nem o que enviar pra elas e nem o que esperar da resposta. Você então coloca energia e cria funções de validação dos inputs, documentação via Swagger e expõe uma especificação OpenAPI e um arquivo Postman...

Agora o cliente da API está munido de tudo que precisa, certo? Na verdade agora ele vai ler a documentação, testar as respostas e mapear os tipos de entrada e saída para a sua linguagem pra só então poder começar a integrar o cliente, rezando pra não ter feito algo errado sem querer.

Existem ferramentas pra tentar contornar, como o fastify-type-provider-zod (servidor) e orval (cliente), o qual não testei o suficiente para dar minha opinião se conseguem se realmente oferecer uma boa experiência de desenvolvimento. Mas o ponto aqui é: O GraphQL resolve esse problema por definição.

O GraphQL força você a definir os tipos dos Inputs, e Objetos de saída e você só precisa:

  1. Criar as operações (queries e mutations) e definir qual a entrada e saída.
  2. Visualizar no Playground as operações magicamente aparecendo.
  3. Usar uma ferramenta codegen (se você usa typescript) que vai gerar automaticamente todas as definições de tipos e mapear as possíveis operações em funções pra usar no seu cliente a partir da Introspecção automática do Schema GraphQL gerado.

Atualizou um Input, objeto de saída ou operação? Rode o codegen novamente e você terá os novos tipos.

Benefício 2: O Schema é "vivo"

Você provavelmente tem uma entidade no seu banco de dados chamado "User", certo?

Como num Ifood da vida, talvez esse "User" possa ter vários "Address"...

No Rest, você pode precisar criar uma rota pra consultar usuários, e uma nova rota pra consultar os endereços. Daí você trata o resultado dessas duas rotas e agora você tem usuários com endereços.

No Pothos Graphql (Biblioteca de construção de Schemas code-first), você pode integrar com o Prisma (ORM) e realizar consultas por usuários onde cada usuáro virá com seus endereços apenas realizando 1 consulta otimizada no seu banco de dados.

Aqui, o Objeto de usuário que você definiu no servidor sabe que ele tem N endereços e lhe permite consultar livremente todas as relações...

Você precisa apenas definir 1 única operação query "findUsers" e:

  • Quer consultar todos os usuários chamados de "Cauê"? Use "findUsers"
  • Quer consultar últimos 10 usuários que tem o endereço na cidade de "São Paulo" e pegar apenas os endereços cadastrados dessa cidade? Use "findUsers"

Use ferramentas de Generators do Prisma e magicamente você tem todas as operações e relações do banco no seu Schema...

Benefício 3: A padronização é sua amiga

Quer alterar algo no sistema? Mutation. Quer consultar algo? Query. Quer observar dados em tempo real? Mutations.

Pode parecer algo bobo, mas some isso ao fato de cada "entidade" ser mapeada num "Object" e você tem a faca e queijo para resolver problemas de cache.

Existem apenas duas coisas difíceis na ciência da computação: invalidação de cache e nomear coisas.
— Phil Karlton

Bom, agora vai sobrar mais tempo pra você focar no que realmente importa, nomear coisas D:

Benefício 4: Muitas ferramentas pra lhe ajudar

Aqui eu falei sobre as ferramentas do Pothos e Graphql Codegens, mas GraphQL pode ser muito extendido tanto na layer de definição de schema quanto de execução usando o Yoga.

  1. Quer dividir seu schema? GraphQL federation
  2. Quer padronizar seus erros? Existem ferramentas
  3. Rastrear operações? Tem ferramentas
  4. Validações complexas de inputs? Tem ferramentas
  5. Quer criar seus hooks React automaticamente? Apollo Client (cria tudo igual o Tanstack Query)

Segue aqui o link pra algumas páginas listando alguns plugins que uso no dia a dia:

Tirando alguns elefantes da frente

  1. Complexidade? GraphQL é uma especificação e apenas define um padrão para suas requisições HTTP. Nada mais, nada menos. A única "complexidade" é instalar as ferramentas corretas para tirar proveito disso.
  2. Under/Overteching? Apenas a cereja do bolo.
  3. Performance/Segurança? Dá uma olhada aqui https://hygraph.com/graphql-survey-2024

GraphQL vai substituir o Rest?

Não. Mas acredito que a pergunta aqui deveria ser: "O GraphQL vai se tornar mais popular que o REST?" E isso, eu acredito que sim.

Na minha visão, se você busca eficiência, flexibilidade e uma experiência superior para desenvolvedores, o GraphQL não é só uma alternativa ao REST, é uma evolução natural.

Carregando publicação patrocinada...
1

GraphQL vs. REST: Por que o REST ainda é a escolha certa para projetos grandes (e por que a era de ouro do GraphQL já passou)

1. Complexidade desnecessária em projetos grandes

O GraphQL é frequentemente vendido como uma solução mágica para problemas como underfetching e overfetching. No entanto, em projetos grandes, a complexidade que ele introduz pode se tornar um pesadelo.

  • Esquemas e Resolvers: Enquanto no REST você tem endpoints claros e bem definidos, no GraphQL você precisa gerenciar esquemas complexos e resolvers para cada tipo de dado. Em projetos grandes, isso pode levar a uma explosão de complexidade, especialmente quando você tem dezenas (ou centenas) de entidades e relações.
  • Problema do N+1: Consultas aninhadas no GraphQL podem resultar em múltiplas chamadas ao banco de dados, o que prejudica a performance. Embora existam soluções como o DataLoader, elas adicionam ainda mais complexidade ao sistema.
  • Dificuldade de otimização: Em APIs REST, é mais fácil otimizar endpoints específicos para atender a necessidades de performance. No GraphQL, como o cliente pode solicitar qualquer combinação de dados, otimizar consultas se torna muito mais desafiador.

2. Falta de maturidade em ferramentas e ecossistema

Enquanto o REST é uma tecnologia madura e amplamente adotada, o ecossistema do GraphQL ainda está em evolução — e isso pode ser um problema em projetos grandes.

  • Ferramentas imaturas: Muitas ferramentas do ecossistema GraphQL, como codegen e plugins de validação, ainda não são tão robustas quanto as equivalentes no mundo REST. Isso pode levar a problemas de integração e manutenção.
  • Dificuldade de debugging: Debuggar problemas em APIs GraphQL pode ser muito mais complicado do que em REST, especialmente quando você lida com consultas complexas e resolvers aninhados.
  • Falta de padrões consolidados: Enquanto o REST tem padrões bem estabelecidos (como o uso de verbos HTTP e status codes), o GraphQL ainda carece de convenções claras para coisas como tratamento de erros, paginação e versionamento.

3. Performance e escalabilidade

Um dos grandes mitos sobre o GraphQL é que ele é sempre mais performático que o REST. Na prática, isso nem sempre é verdade — especialmente em projetos grandes.

  • Overhead de consultas: O GraphQL permite que os clientes solicitem exatamente os dados que precisam, mas isso vem com um custo: o servidor precisa processar consultas complexas e montar respostas sob demanda. Em sistemas com alto volume de requisições, isso pode levar a problemas de performance.
  • Caching: O REST é muito mais fácil de ser cacheado em nível de HTTP, graças ao uso de verbos padrão e URLs bem definidas. No GraphQL, o caching é mais complicado, já que todas as consultas são feitas via POST (na maioria das implementações) e não há URLs únicas para cada recurso.
  • Escalabilidade: Em projetos grandes, a escalabilidade horizontal é crucial. APIs REST são mais fáceis de escalar, pois você pode distribuir a carga entre diferentes endpoints. No GraphQL, como tudo passa por um único endpoint, escalar pode ser mais desafiador.

4. Grandes empresas estão abandonando o GraphQL

A era de ouro do GraphQL já passou, e muitas empresas que adotaram a tecnologia estão reconsiderando suas escolhas.

  • Volta ao REST: Empresas como o GitHub e o Shopify, que foram early adopters do GraphQL, estão migrando parte de suas APIs de volta para REST ou adotando SDKs. O motivo? A complexidade e o custo de manutenção do GraphQL em larga escala.
  • Uso de SDKs: Em vez de expor APIs GraphQL, muitas empresas estão optando por SDKs específicos para suas plataformas. Isso permite um controle maior sobre como os dados são consumidos e reduz a complexidade no lado do cliente.
  • Custo de manutenção: Manter uma API GraphQL em grande escala é caro. Além da complexidade técnica, você precisa de equipes especializadas para gerenciar esquemas, resolvers e otimizações. Para muitas empresas, o custo-benefício simplesmente não vale a pena.

5. REST é mais simples e previsível

No final do dia, o REST é uma tecnologia mais simples e previsível — e isso é uma vantagem enorme em projetos grandes.

  • Endpoints claros: No REST, cada endpoint tem uma responsabilidade clara e bem definida. Isso facilita a compreensão, a documentação e a manutenção da API.
  • Fácil de testar: Testar APIs REST é muito mais simples, já que cada endpoint pode ser testado de forma isolada. No GraphQL, como as consultas são dinâmicas, os testes tendem a ser mais complexos.
  • Menor curva de aprendizado: REST é uma tecnologia madura e amplamente conhecida. Novos desenvolvedores podem começar a trabalhar com APIs REST muito mais rapidamente do que com GraphQL.

Conclusão

O GraphQL tem suas vantagens, especialmente em cenários onde a flexibilidade e a capacidade de evitar under/overfetching são críticas. No entanto, para projetos grandes e complexos, o REST ainda é a escolha superior. Ele é mais simples, mais previsível e mais fácil de escalar — e, como estamos vendo no mercado, muitas empresas estão percebendo isso e voltando ao REST ou adotando SDKs.

A era de ouro do GraphQL pode ter passado, mas isso não significa que a tecnologia não tenha seu lugar. Ela pode ser uma ótima escolha para projetos menores ou com necessidades específicas. No entanto, para a maioria dos projetos grandes, o REST continua sendo a opção mais robusta e confiável.

Então, antes de pular no hype do GraphQL, avalie cuidadosamente as necessidades do seu projeto. Às vezes, a simplicidade do REST é exatamente o que você precisa.

1

Opa, Nikolavn
Aprecio seu comentário, e fico feliz pela oportunidade de aprofundarmos essa discussão

Li seus pontos um a um, e só consegui concordar com um ponto: Que é o dos Sdks. Realmente se uma empresa pode investir tempo nelas, os clientes agradecem.

Mas em quanto aos outros pontos, nenhum deles se aplica nas stacks que uso, inclusive no ponto de performance seu ponto contraria totalmente o meu em que cito consultas otimizadas ao banco. Estou curioso, já tentou usar graphql num projeto pessoal ou profissional? Quais tecnologias usou? Quais desses pontos realmente lhe afetou?

Por fim, o ponto que mais fiquei curioso foi você citar das empresas deixando de usar graphql, e citando o Shopify. Eles estão cada vez focando na frase: Graphql é o futuro.

https://www.shopify.com/partners/blog/all-in-on-graphql
All-in on GraphQL: the future of app development at Shopify (2024)

0

Deixando claro que concordamos em discordar, meu objetivo aqui não é criticar a sua visão, e sim apresentar o meu contra-argumento. De qualquer forma, ótimo artigo, btw.

1

Talvez um dos problemas seja você disponibilizar o schema das suas tabelas e com isto saberem quais tabelas e colunas tem.
Não que isto seja de fato um problema para todos os projetos.

2

Nesse caso, nos projetos que isso for um problema, podemos customizar a vontade.

Renomear/remover tabelas/colunas apenas no schema graphql, mantendo a segurança de tipos do Typescript.

1