Por Que Usar TypeScript com GraphQL?
GraphQL é uma linguagem de consulta para APIs que permite solicitar dados de forma precisa e eficiente. Quando combinamos GraphQL com TypeScript, conseguimos criar APIs fortemente tipadas que garantem a integridade dos dados tanto no lado do servidor quanto no cliente. O TypeScript fornece tipagem estática, enquanto o GraphQL assegura que as consultas e mutações sigam a estrutura definida, resultando em uma API mais segura, previsível e fácil de manter.
Configurando TypeScript com GraphQL
Para começar, precisamos configurar um ambiente com Node.js, TypeScript e GraphQL. Aqui está como configurar o projeto.
1. Instalando Dependências
No terminal, execute o seguinte comando para instalar as dependências necessárias:
npm install express express-graphql graphql
npm install --save-dev typescript ts-node @types/express @types/graphql
Os pacotes express
e express-graphql
são usados para configurar o servidor, graphql
fornece o núcleo do GraphQL, e as definições de tipos são instaladas para garantir que o TypeScript entenda os tipos do GraphQL e do Express.
2. Configurando o tsconfig.json
Adicione o arquivo tsconfig.json
à raiz do seu projeto com a seguinte configuração básica:
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"]
}
Esse arquivo configura o TypeScript para compilar o código para ES6 e usar módulos CommonJS, que são padrão no Node.js.
Criando o Esquema GraphQL com TypeScript
Agora que temos as dependências e o ambiente configurados, vamos criar uma API GraphQL simples com TypeScript. Para isso, começaremos criando um esquema básico de GraphQL.
1. Definindo o Esquema
Em src/schema.ts
, crie o seguinte código para definir um esquema simples que consulta um Usuario
com nome
e idade
:
import { GraphQLObjectType, GraphQLSchema, GraphQLString, GraphQLInt } from 'graphql';
// Definindo o tipo Usuario
const UsuarioType = new GraphQLObjectType({
name: 'Usuario',
fields: {
nome: { type: GraphQLString },
idade: { type: GraphQLInt }
}
});
// Definindo a query de entrada
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
usuario: {
type: UsuarioType,
resolve() {
return { nome: 'Mauro Souza', idade: 30 };
}
}
}
});
// Criando o esquema
export const schema = new GraphQLSchema({
query: RootQuery
});
Neste exemplo, definimos um tipo Usuario
com os campos nome
(string) e idade
(inteiro), e uma query de entrada que retorna um objeto de exemplo com esses dados.
2. Configurando o Servidor Express com GraphQL
No arquivo src/index.ts
, crie o servidor Express que utiliza GraphQL:
import express from 'express';
import { graphqlHTTP } from 'express-graphql';
import { schema } from './schema';
const app = express();
app.use('/graphql', graphqlHTTP({
schema,
graphiql: true
}));
const porta = 4000;
app.listen(porta, () => {
console.log(`Servidor GraphQL rodando na porta ${porta}`);
});
Aqui, estamos usando o middleware express-graphql
para expor o endpoint /graphql
e ativar a interface de desenvolvimento GraphiQL
, que facilita a execução de consultas e a visualização do esquema.
Executando o Servidor GraphQL
Para iniciar o servidor GraphQL, execute o seguinte comando no terminal:
npx ts-node src/index.ts
O servidor será iniciado na porta 4000. Agora, acesse http://localhost:4000/graphql
no navegador para visualizar o GraphiQL e fazer consultas.
1. Exemplo de Consulta
No GraphiQL, faça a seguinte consulta para obter o nome e a idade do usuário:
{
usuario {
nome
idade
}
}
A resposta será semelhante a:
{
"data": {
"usuario": {
"nome": "Mauro Souza",
"idade": 30
}
}
}
Usando Tipos Personalizados com TypeScript
Para garantir a integridade dos dados no servidor, podemos criar tipos personalizados em TypeScript para tipar o corpo das respostas e a lógica de negócios.
1. Definindo Tipos para o Objeto Usuario
Crie uma interface para o tipo Usuario
no arquivo src/types.ts
:
export interface Usuario {
nome: string;
idade: number;
}
2. Usando a Interface no Resolvedor
Agora, use a interface Usuario
no arquivo src/schema.ts
para garantir que os dados do usuário estejam corretamente tipados:
import { Usuario } from './types';
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
usuario: {
type: UsuarioType,
resolve(): Usuario {
return { nome: 'Mauro Souza', idade: 30 };
}
}
}
});
Com isso, o TypeScript garantirá que os dados retornados pela função resolve
sigam a estrutura definida pela interface Usuario
.
Adicionando Mutações ao Esquema
As mutações permitem modificar dados no servidor. Vamos adicionar uma mutação para criar um novo usuário e retornar seus dados.
1. Exemplo de Mutação
No arquivo src/schema.ts
, adicione o seguinte código para definir uma mutação:
const Mutation = new GraphQLObjectType({
name: 'Mutation',
fields: {
criarUsuario: {
type: UsuarioType,
args: {
nome: { type: GraphQLString },
idade: { type: GraphQLInt }
},
resolve(parent, args): Usuario {
return { nome: args.nome, idade: args.idade };
}
}
}
});
export const schema = new GraphQLSchema({
query: RootQuery,
mutation: Mutation
});
A mutação criarUsuario
aceita os argumentos nome
e idade
e retorna o novo usuário criado. O TypeScript garante que os dados de entrada e saída estejam corretos, seguindo a tipagem definida.
2. Fazendo uma Mutação
No GraphiQL, faça a seguinte mutação para criar um novo usuário:
mutation {
criarUsuario(nome: "João", idade: 25) {
nome
idade
}
}
A resposta será semelhante a:
{
"data": {
"criarUsuario": {
"nome": "João",
"idade": 25
}
}
}
Boas Práticas ao Usar TypeScript com GraphQL
- Use Interfaces para Tipagem Forte: Sempre defina interfaces para os dados que estão sendo consultados ou modificados, garantindo que o TypeScript valide a estrutura.
- Combine Resolvedores com Tipos: Garanta que as funções
resolve
estejam sempre retornando os tipos corretos usando as interfaces TypeScript. - Valide Argumentos: Ao definir mutações, valide os argumentos com o GraphQL e adicione validações adicionais no TypeScript para garantir a integridade dos dados recebidos.
- Organize o Código: Mantenha o esquema, tipos e resolvedores bem organizados em arquivos separados para melhorar a manutenibilidade.
Conclusão
Combinar TypeScript com GraphQL permite criar APIs fortemente tipadas que garantem a integridade dos dados e a segurança durante o desenvolvimento. O uso de tipos no lado do servidor, juntamente com o esquema GraphQL, resulta em APIs mais previsíveis e seguras. Seguindo boas práticas e utilizando as capacidades do TypeScript, você pode construir APIs escaláveis e fáceis de manter, aproveitando ao máximo as vantagens da tipagem estática.