[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:
- Criar as operações (queries e mutations) e definir qual a entrada e saída.
- Visualizar no Playground as operações magicamente aparecendo.
- 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.
- Quer dividir seu schema? GraphQL federation
- Quer padronizar seus erros? Existem ferramentas
- Rastrear operações? Tem ferramentas
- Validações complexas de inputs? Tem ferramentas
- 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:
- https://pothos-graphql.dev/docs/plugins
- https://the-guild.dev/graphql/yoga-server/docs/features/envelop-plugins
Tirando alguns elefantes da frente
- 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.
- Under/Overteching? Apenas a cereja do bolo.
- 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.