No cenário em constante evolução do desenvolvimento web, o GraphQL surgiu como uma alternativa poderosa às APIs REST tradicionais, oferecendo aos clientes a capacidade de solicitar precisamente os dados de que precisam. No entanto, essa flexibilidade pode introduzir um novo conjunto de desafios, particularmente quando se trata de manter a segurança de tipos (type safety) entre o frontend e o backend. É aqui que entra o graphql-codegen
, uma ferramenta revolucionária que automatiza a geração de código tipado a partir do seu schema GraphQL, turbinando seu fluxo de trabalho de desenvolvimento e eliminando toda uma classe de erros em tempo de execução.
Este artigo servirá como seu guia para entender e dominar o graphql-codegen
. Começaremos com os conceitos fundamentais, passaremos por um exemplo prático e passo a passo de como configurar a ferramenta e exploraremos as melhores práticas para integrá-la aos seus projetos. Ao final deste guia, você estará apto a usar o graphql-codegen
para construir aplicações mais robustas, fáceis de manter e com segurança de tipos.
Quer uma plataforma integrada e Tudo-em-Um para sua Equipe de Desenvolvimento trabalhar em conjunto com produtividade máxima?
Apidog entrega todas as suas demandas e substitui o Postman por um preço muito mais acessível!
O que é graphql-codegen
e Por Que Você Precisa Dele?
Em sua essência, o graphql-codegen
é uma ferramenta de linha de comando que inspeciona seu schema GraphQL e suas operações GraphQL (queries, mutations e subscriptions) e gera código em uma variedade de linguagens. Para os propósitos deste guia para iniciantes, focaremos em seu caso de uso mais popular: gerar tipos e hooks TypeScript para aplicações frontend.
O problema principal que o graphql-codegen
resolve é o processo tedioso e propenso a erros de escrever manualmente interfaces TypeScript para as estruturas de dados da sua API GraphQL e os resultados das suas queries. Sem ele, os desenvolvedores ficam trabalhando com dados não tipados (perdendo os benefícios do TypeScript) ou gastam um tempo significativo criando e mantendo tipos que podem facilmente ficar desatualizados à medida que a API evolui.
Os benefícios de adotar o graphql-codegen
são múltiplos:
- Segurança de Tipos de Ponta a Ponta: Ao gerar tipos diretamente do seu schema, o
graphql-codegen
garante que seu código frontend esteja sempre sincronizado com o modelo de dados do seu backend. Isso significa que você detecta erros relacionados a tipos em tempo de compilação, muito antes que cheguem aos seus usuários. - Experiência do Desenvolvedor Aprimorada: Com tipos gerados, você obtém recursos como autocompletar e sugestões inteligentes no seu editor de código, tornando o desenvolvimento mais rápido e eficiente. Chega de adivinhar a forma das respostas da sua API!
- Boilerplate Reduzido: O
graphql-codegen
pode gerar não apenas tipos, mas também hooks prontos para uso para clientes GraphQL populares como Apollo Client e React Query. Isso elimina a necessidade de escrever lógica repetitiva de busca de dados. - Manutenibilidade Aumentada: Quando o schema da sua API muda, um simples comando é tudo o que é preciso para regenerar seus tipos. Isso torna sua base de código muito mais fácil de manter e refatorar ao longo do tempo.
Essa abordagem se alinha perfeitamente com a filosofia de desenvolvimento "schema-first", onde o schema GraphQL serve como a única fonte de verdade para sua API.
Primeiros Passos: Sua Primeira Configuração do graphql-codegen
Vamos mergulhar nos aspectos práticos do uso do graphql-codegen
. Para este tutorial, assumiremos que você tem um entendimento básico de GraphQL, TypeScript e que tem o Node.js e um gerenciador de pacotes (como npm ou yarn) instalados.
Nosso objetivo é configurar o graphql-codegen
para uma aplicação React simples que exibe uma lista de posts de blog.
Passo 1: Inicialização do Projeto e Dependências
Primeiro, vamos criar um novo projeto React com TypeScript e instalar as dependências necessárias.Bash
npx create-react-app my-blog --template typescript
cd my-blog
npm install @apollo/client graphql
npm install -D @graphql-codegen/cli @graphql-codegen/client-preset typescript
Aqui está um detalhamento das dependências que instalamos:
@apollo/client
: Um cliente GraphQL popular para React.graphql
: Uma dependência peer necessária tanto pelo Apollo Client quanto pelographql-codegen
.@graphql-codegen/cli
: A interface de linha de comando para ographql-codegen
.@graphql-codegen/client-preset
: Um preset moderno e simplificado que facilita a configuração para aplicações client-side.typescript
: O compilador TypeScript.
Passo 2: O Assistente de Inicialização do graphql-codegen
A maneira mais fácil de começar com o graphql-codegen
é usando seu assistente de inicialização. Execute o seguinte comando no diretório raiz do seu projeto:Bash
npx graphql-codegen init
O assistente fará uma série de perguntas para ajudar a configurar seu projeto. Aqui está um conjunto típico de respostas para o cenário da nossa aplicação de blog:
- Que tipo de aplicação você está construindo?
Aplicação construída com React
- Onde está seu schema? Forneça a URL para o endpoint da sua API GraphQL. Para este tutorial, podemos usar uma API de exemplo publicamente disponível:
https://swapi-graphql.netlify.app/.netlify/functions/index
- Onde estão suas operações e fragmentos?
src/**/*.tsx
(Isso diz aographql-codegen
para procurar por queries GraphQL em todos os arquivos.tsx
dentro do diretóriosrc
). - Escolha os plugins: O assistente sugerirá um conjunto de plugins. Os padrões, incluindo
typescript
,typescript-operations
etypescript-react-apollo
, são um ótimo ponto de partida. - Onde escrever a saída?
src/gql/
(Isso criará um novo diretóriosrc/gql
para armazenar os arquivos gerados). - Você quer gerar um arquivo de introspecção?
Sim
(Isso pode ser útil para desenvolvimento local e extensões de IDE). - Como nomear o arquivo de configuração?
codegen.ts
- Qual script no package.json deve executar o codegen?
codegen
Após responder a essas perguntas, o assistente criará um arquivo codegen.ts
na raiz do seu projeto e adicionará um script codegen
ao seu package.json
.
Passo 3: Entendendo o Arquivo de Configuração (codegen.ts
)
O arquivo codegen.ts
é o coração da sua configuração do graphql-codegen
. Vamos dar uma olhada em uma versão simplificada do que o assistente gera:TypeScript
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
overwrite: true,
schema: "https://swapi-graphql.netlify.app/.netlify/functions/index",
documents: "src/**/*.tsx",
generates: {
"src/gql/": {
preset: "client",
plugins: []
}
}
};
export default config;
Vamos detalhar as principais opções de configuração:
overwrite: true
: Isso garante que os arquivos gerados existentes sejam sobrescritos toda vez que você executar o comando.schema
: Isso aponta para a fonte do seu schema GraphQL. Pode ser uma URL para um endpoint ativo, um arquivo local.graphql
ou.json
.documents
: Este é um padrão glob que diz aographql-codegen
onde encontrar suas operações GraphQL (queries, mutations e fragments).generates
: Esta é a parte mais importante da configuração. É um objeto onde cada chave representa um arquivo ou diretório de saída, e o valor define o que gerar.preset: "client"
: Oclient-preset
é uma maneira poderosa e recomendada de configurar ographql-codegen
para aplicações frontend. Ele agrupa vários plugins e oferece uma experiência simplificada. Ele gera uma funçãographql
que você usará para escrever suas queries.
Passo 4: Escrevendo Sua Primeira Query GraphQL
Agora que o graphql-codegen
está configurado, vamos escrever uma query GraphQL para buscar nossos posts de blog. Crie um novo arquivo src/components/Posts.tsx
:TypeScript
import { gql } from '../gql/gql';
import { useQuery } from '@apollo/client';
const GET_POSTS = gql(`
query GetPosts {
allFilms {
films {
id
title
director
releaseDate
}
}
}
`);
const Posts = () => {
const { loading, error, data } = useQuery(GET_POSTS);
if (loading) return <p>Carregando...</p>;
if (error) return <p>Erro :(</p>;
return (
<div>
{data?.allFilms?.films?.map((film) => (
<div key={film?.id}>
<h2>{film?.title}</h2>
<p>Diretor: {film?.director}</p>
<p>Data de Lançamento: {film?.releaseDate}</p>
</div>
))}
</div>
);
};
export default Posts;
Observe que estamos importando uma função gql
do arquivo gerado src/gql/gql.ts
. Esta é a função gql
fornecida pelo client-preset
e é o que permite a mágica da inferência de tipos.
Passo 5: Executando o graphql-codegen
e Vendo a Mágica
Agora, execute o script codegen
do seu package.json
:Bash
npm run codegen
Este comando irá inspecionar o schema, encontrar sua query GET_POSTS
e gerar os tipos TypeScript correspondentes no diretório src/gql
.
Se você inspecionar agora o objeto data
retornado pelo hook useQuery
em Posts.tsx
, verá que ele está totalmente tipado! Sua IDE fornecerá autocompletar para data.allFilms.films
, e o TypeScript avisará se você tentar acessar um campo que não existe na query.
Um Mergulho Mais Profundo: Um Exemplo Prático de Frontend de Blog
Vamos expandir nosso exemplo para solidificar seu entendimento. Imagine que nosso blog tenha um schema mais tradicional:GraphQL
type Author {
id: ID!
name: String!
}
type Post {
id: ID!
title: String!
content: String!
author: Author!
}
type Query {
posts: [Post!]!
post(id: ID!): Post
}
type Mutation {
createPost(title: String!, content: String!, authorId: ID!): Post!
}
Vamos assumir que este schema está rodando em http://localhost:4000/graphql
. Atualizaríamos nosso codegen.ts
de acordo:TypeScript
// codegen.ts
// ...
schema: "http://localhost:4000/graphql",
// ...
Agora, vamos criar um componente para exibir um único post e outro para criar um novo.
Buscando um Único PostTypeScript
// src/components/Post.tsx
import { gql } from '../gql/gql';
import { useQuery } from '@apollo/client';
import { useParams } from 'react-router-dom';
const GET_POST = gql(`
query GetPost($id: ID!) {
post(id: $id) {
id
title
content
author {
id
name
}
}
}
`);
const Post = () => {
const { id } = useParams<{ id: string }>();
const { loading, error, data } = useQuery(GET_POST, {
variables: { id },
});
if (loading) return <p>Carregando...</p>;
if (error) return <p>Erro :(</p>;
return (
<div>
<h2>{data?.post?.title}</h2>
<p>Por {data?.post?.author?.name}</p>
<p>{data?.post?.content}</p>
</div>
);
};
export default Post;
Após executar npm run codegen
, os tipos para a GetPostQuery
e suas variáveis serão gerados, fornecendo segurança de tipos para o hook useQuery
e seu resultado.
Criando um Novo PostTypeScript
// src/components/CreatePost.tsx
import { gql } from '../gql/gql';
import { useMutation } from '@apollo/client';
import { useState } from 'react';
const CREATE_POST = gql(`
mutation CreatePost($title: String!, $content: String!, $authorId: ID!) {
createPost(title: $title, content: $content, authorId: $authorId) {
id
}
}
`);
const CreatePost = () => {
const [title, setTitle] = useState('');
const [content, setContent] = useState('');
const [createPost, { data, loading, error }] = useMutation(CREATE_POST);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
createPost({ variables: { title, content, authorId: '1' } }); // Assumindo authorId '1' para simplificar
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Título"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<textarea
placeholder="Conteúdo"
value={content}
onChange={(e) => setContent(e.target.value)}
/>
<button type="submit" disabled={loading}>
{loading ? 'Criando...' : 'Criar Post'}
</button>
{error && <p>Erro ao criar post: {error.message}</p>}
{data && <p>Post criado com ID: {data.createPost.id}</p>}
</form>
);
};
export default CreatePost;
Aqui, o graphql-codegen
gera os tipos para a CreatePostMutation
e suas variáveis. Isso garante que, ao chamar a função createPost
, você está passando os tipos corretos para title
, content
e authorId
.
Conceitos Avançados e Melhores Práticas
À medida que você se sentir mais confortável com o graphql-codegen
, encontrará recursos mais avançados e melhores práticas:
Fragments: O graphql-codegen
tem excelente suporte para fragments GraphQL. Você pode definir fragments em seus arquivos .tsx
e o graphql-codegen
lidará corretamente com os tipos, promovendo dependências de dados reutilizáveis e co-localizadas para seus componentes.
Usando Arquivos .graphql
: Para uma melhor separação de preocupações, você pode escrever suas queries, mutations e fragments GraphQL em arquivos .graphql
dedicados. Basta atualizar o array documents
em seu codegen.ts
para incluir esta extensão de arquivo: documents: ["src/**/*.tsx", "src/**/*.graphql"]
.
Custom Scalars: Se o seu schema GraphQL usa scalars personalizados (por exemplo, Date
, JSON
), você pode mapeá-los para os tipos TypeScript correspondentes em seu arquivo codegen.ts
para manter a segurança de tipos.
Modo Watch: Para uma experiência de desenvolvimento contínua, você pode executar o graphql-codegen
em modo watch. Isso regenerará automaticamente seus tipos sempre que você salvar um arquivo contendo uma operação GraphQL. Basta adicionar a flag --watch
ao seu script codegen
no package.json
: "codegen": "graphql-codegen --watch"
.
Solução de Problemas Comuns
Embora o graphql-codegen
seja uma ferramenta poderosa, você pode encontrar alguns problemas comuns como iniciante:
- "Unable to find schema": Este erro geralmente significa que o caminho do
schema
em seucodegen.ts
está incorreto ou que o servidor GraphQL não está rodando no endereço especificado. - Erros de Configuração de Plugin: Certifique-se de que você instalou todos os plugins necessários e que suas configurações em
codegen.ts
estão corretas. graphql
Peer Dependency Issues: Certifique-se de ter ographql
instalado como uma dependência direta em seu projeto.
Conclusão: Abrace o Futuro com Segurança de Tipos
O graphql-codegen
é mais do que apenas uma ferramenta de geração de código; é uma mudança de paradigma em como construímos aplicações com GraphQL. Ao abraçar a automação e alavancar o poder do seu schema, você pode criar bases de código mais robustas, fáceis de manter e agradáveis de trabalhar.
Este tutorial forneceu a você uma base sólida para começar com o graphql-codegen
. Cobrimos os conceitos principais, passamos por um exemplo prático e abordamos as melhores práticas. A jornada não termina aqui. O ecossistema do graphql-codegen
é vasto, com uma rica coleção de plugins que atendem a vários frameworks e casos de uso. Encorajo você a explorar a documentação oficial, experimentar diferentes plugins e descobrir como o graphql-codegen
pode revolucionar seu fluxo de trabalho de desenvolvimento GraphQL. Boa codificação!
Quer uma plataforma integrada e Tudo-em-Um para sua Equipe de Desenvolvimento trabalhar em conjunto com produtividade máxima?
Apidog entrega todas as suas demandas e substitui o Postman por um preço muito mais acessível!