Introdução ao GraphQL API com TypeScript
GraphQL é uma linguagem de consulta moderna para APIs que permite aos clientes solicitar apenas os dados de que realmente precisam. Em combinação com TypeScript, que adiciona tipagem estrita, o desenvolvimento se torna mais previsível e seguro. Neste tutorial passo a passo, criaremos uma API GraphQL completa em TypeScript, usando ferramentas populares e melhores práticas.
Por que escolher GraphQL com TypeScript? Primeiro, você obtém autocompletar e verificação de tipos em tempo de compilação. Segundo, GraphQL permite combinar várias consultas em uma, reduzindo o número de requisições de rede. Terceiro, TypeScript é ideal para descrever estruturas de dados gráficas complexas.
Configuração do projeto e instalação de dependências
Para começar, criaremos um novo projeto e instalaremos os pacotes necessários. Usaremos Apollo Server — o servidor mais popular para GraphQL, e TypeGraphQL para integração conveniente com TypeScript.
mkdir graphql-ts-tutorialcd graphql-ts-tutorialnpm init -ynpm install apollo-server graphql reflect-metadata class-validatornpm install typescript type-graphql @types/node --save-devnpx tsc --initApós a instalação, configuraremos o tsconfig.json. Certifique-se de que as seguintes opções estejam incluídas:
{ "compilerOptions": { "target": "ES2020", "module": "commonjs", "lib": ["ES2020"], "experimentalDecorators": true, "emitDecoratorMetadata": true, "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true }}Criaremos a estrutura de pastas:
src/ ├── index.ts ├── resolvers/ │ └── user.resolver.ts ├── schemas/ │ └── user.schema.ts └── data/ └── users.tsCriação do schema e tipos de dados
No TypeGraphQL, os tipos de dados são descritos usando decorators. Criaremos um modelo de usuário e um tipo de dados de entrada para a mutação.
// src/schemas/user.schema.tsimport { ObjectType, Field, ID, InputType } from "type-graphql";
@ObjectType()export class User { @Field(() => ID) id!: number;
@Field() name!: string;
@Field() email!: string;
@Field({ nullable: true }) age?: number;}
@InputType()export class CreateUserInput { @Field() name!: string;
@Field() email!: string;
@Field({ nullable: true }) age?: number;}Observe o uso de @ObjectType() para descrever os tipos de retorno e @InputType() para os parâmetros de entrada. Isso permite que o TypeGraphQL gere automaticamente o schema GraphQL.
Implementação dos resolvers
Resolvers são funções que processam as consultas e retornam dados. Criaremos um array simples em memória para armazenar os usuários.
// src/data/users.tsimport { User } from "../schemas/user.schema";
export const users: User[] = [ { id: 1, name: "Ivan Petrov", email: "ivan@example.com", age: 28 }, { id: 2, name: "Maria Sidorova", email: "maria@example.com", age: 32 },];Agora escreveremos os resolvers para consultas e mutações:
// src/resolvers/user.resolver.tsimport { Resolver, Query, Mutation, Arg, Int } from "type-graphql";import { User, CreateUserInput } from "../schemas/user.schema";import { users } from "../data/users";
@Resolver()export class UserResolver { @Query(() => [User]) async getAllUsers(): Promise<User[]> { return users; }
@Query(() => User, { nullable: true }) async getUserById( @Arg("id", () => Int) id: number ): Promise<User | undefined> { return users.find(user => user.id === id); }
@Mutation(() => User) async createUser( @Arg("input") input: CreateUserInput ): Promise<User> { const newUser: User =
```