GraphQL oferece flexibilidade incomparável para APIs modernas, permitindo que o cliente solicite exatamente os dados que precisa. Com TypeGraphQL e agentes de IA, você pode criar uma API GraphQL type-safe e eficiente em horas. Neste tutorial, você vai aprender a construir uma API GraphQL com TypeGraphQL usando Claude Code e Codex de forma orquestrada.
O que vamos construir
Vamos desenvolver uma API GraphQL para uma plataforma de cursos online:
- Queries: cursos, aulas, alunos, instrutores, categorias
- Mutations: matrícula, progresso, avaliações, CRUD de cursos
- Subscriptions: notificações em tempo real
- Autenticação via JWT com context
- DataLoader para evitar N+1
- Validação com class-validator
Imagem sugerida: GraphQL Playground mostrando schema completo com queries, mutations e subscriptions da plataforma de cursos.
Setup com Claude Code
Claude Code configura o projeto Apollo Server com TypeGraphQL.
Inicialização
claude "Crie um projeto Node.js com TypeScript, Apollo Server 4 e TypeGraphQL para uma API GraphQL de plataforma de cursos. Instale: apollo-server, @apollo/server, graphql, type-graphql, reflect-metadata, prisma, @prisma/client, class-validator, jsonwebtoken, bcryptjs, dataloader, graphql-subscriptions. Instale devDependencies: typescript, ts-node-dev, @types/node, @types/jsonwebtoken, jest, @types/jest. Configure tsconfig.json com experimentalDecorators e emitDecoratorMetadata. Estrutura: src/schemas (object types), src/resolvers (queries, mutations, subscriptions), src/middleware (auth), src/loaders (dataloader), src/services, prisma/schema.prisma."
Schemas e Object Types com Codex
Codex gera os Object Types do TypeGraphQL com decoradores, que seguem um padrão previsível.
Object Types
opencode "Crie src/schemas/Course.ts com ObjectType do TypeGraphQL:
@ObjectType() class Course:
@Field(() => ID) id: string
@Field() title: string
@Field() slug: string
@Field({ nullable: true }) description?: string
@Field(() => Float) price: number
@Field(() => CourseStatus) status: CourseStatus
@Field(() => [Lesson]) lessons: Lesson[]
@Field(() => Category) category: Category
@Field(() => User) instructor: User
@Field(() => Float, { nullable: true }) averageRating?: number
@Field(() => Int) totalStudents: number
@Field() createdAt: Date
@Field() updatedAt: Date
@ObjectType() class Lesson:
@Field(() => ID) id: string
@Field() title: string
@Field({ nullable: true }) description?: string
@Field() duration: number (segundos)
@Field() videoUrl: string
@Field(() => Int) order: number
@Field() free: boolean
@Field() createdAt: Date
Enum CourseStatus: DRAFT, PUBLISHED, ARCHIVED
Crie tambem User, Category, Enrollment e Review com fields apropriados."
Inputs e Args
opencode "Crie src/schemas/inputs/CourseInputs.ts:
@InputType() CreateCourseInput:
@Field() @Length(3, 200) title: string
@Field({ nullable: true }) @Length(0, 2000) description?: string
@Field(() => Float) @Min(0) price: number
@Field() categoryId: string
@InputType() UpdateCourseInput:
@Field({ nullable: true }) @Length(3, 200) title?: string
@Field({ nullable: true }) @Length(0, 2000) description?: string
@Field(() => Float, { nullable: true }) @Min(0) price?: number
@Field(() => CourseStatus, { nullable: true }) status?: CourseStatus
@Field({ nullable: true }) categoryId?: string
@ArgsType() PaginationArgs:
@Field(() => Int, { defaultValue: 1 }) @Min(1) page: number
@Field(() => Int, { defaultValue: 10 }) @Min(1) @Max(50) limit: number
@ArgsType() CourseFilterArgs extends PaginationArgs:
@Field({ nullable: true }) search?: string
@Field({ nullable: true }) categorySlug?: string
@Field(() => CourseStatus, { nullable: true }) status?: CourseStatus
@Field({ nullable: true }) instructorId?: string"
Resolvers e Queries com Claude Code
Claude Code cria resolvers complexos com lógica de negócio e relacionamentos.
Course Resolver
claude "Crie src/resolvers/CourseResolver.ts (@Resolver(() => Course)):Queries: - courses(filter: CourseFilterArgs): [Course!]! — paginação, filtros, ordenação - course(id: string): Course — busca por ID - courseBySlug(slug: string): Course — busca por slug (SEO) Mutations: - createCourse(data: CreateCourseInput): Course! — cria curso, apenas ADMIN e INSTRUCTOR - updateCourse(id: string, data: UpdateCourseInput): Course! — atualiza, apenas owner e ADMIN - deleteCourse(id: string): Boolean! — soft delete, apenas ADMIN - publishCourse(id: string): Course! — muda status para PUBLISHED Field Resolvers: - lessons(@root course): [Lesson!]! — busca aulas do curso - instructor(@root course): User! — busca instrutor - averageRating(@root course): Float — calcula média de avaliações - totalStudents(@root course): Int — conta matrículas ativas Use @Authorized() para proteger mutations. Injete contexto com @Ctx(). Use DataLoader nos field resolvers."
Enrollment Resolver
claude "Crie src/resolvers/EnrollmentResolver.ts: Queries: - myEnrollments: [Enrollment!]! — matrículas do usuário logado - enrollment(courseId: string): Enrollment — matrícula em curso específico Mutations: - enroll(courseId: string): Enrollment! — cria matrícula, valida se curso está publicado e usuário não está matriculado - updateProgress(courseId: string, lessonId: string, completed: Boolean): Enrollment! — marca aula como concluída, calcula percentual - cancelEnrollment(courseId: string): Boolean! — cancela matrícula Subscriptions: - progressUpdated(courseId: string): ProgressUpdate! — notifica progresso em tempo real"
Mutations e inputs
Vamos gerar as mutations de autenticação e usuário com Codex.
opencode "Crie src/resolvers/AuthResolver.ts: Mutations: - register(data: RegisterInput): AuthPayload! — cria usuário, retorna token - login(email: string, password: string): AuthPayload! — valida credenciais, retorna token - refreshToken(token: string): AuthPayload! — renova token - updateProfile(data: UpdateProfileInput): User! — atualiza perfil do usuário logado AuthPayload: @ObjectType com user: User e token: String RegisterInput: @InputType com name, email, password, confirmPassword com validação class-validator"
Authentication e Authorization
Claude Code configura autenticação e autorização no GraphQL.
claude "Crie src/middleware/auth.ts com:
1. authChecker do TypeGraphQL: verifica @Authorized(), extrai usuario do token JWT no context
2. Context interface: { user?: User, token?: string }
3. buildContext({ req }): extrai token do header Authorization, decodifica, busca usuario no banco4. Gere token e refresh token com expiração configurável Implemente também um guard personalizado @CurrentUser() como parameter decorator."
Testes e performance
Codex gera testes de integração e Claude Code implementa DataLoader.
DataLoader
claude "Crie src/loaders/courseLoaders.ts com DataLoaders: 1. createCourseLoader(): batchea busca de cursos por ID 2. createLessonLoader(): batchea aulas por curso ID 3. createUserLoader(): batchea usuários por ID 4. createEnrollmentCountLoader(): conta matrículas por curso ID Use DataLoader da biblioteca dataloader com cache de 1 segundo."
Testes
opencode "Crie tests/resolvers/course.test.ts: 1. Query courses: deve retornar lista paginada, deve filtrar por status, deve buscar por texto 2. Query course: deve retornar curso por ID, deve retornar null se não existir 3. Mutation createCourse: deve criar curso como admin, deve rejeitar sem role, deve validar campos 4. Mutation publishCourse: deve publicar curso, deve rejeitar se não é owner Use apollo-server-testing ou executeOperation direto."
FAQ — Perguntas Frequentes
Preciso saber GraphQL para criar uma API com agentes de IA?
Sim. Os agentes geram schemas e resolvers, mas você precisa entender tipos, queries e lifecycle do GraphQL para revisar.
TypeGraphQL ou Nexus: qual usar com agentes?
TypeGraphQL é mais adequado porque usa classes e decoradores previsíveis para geração de código por agentes.
Os agentes geram resolvers eficientes (N+1 problem)?
Sim. Claude Code implementa DataLoader para batching e caching, prevenindo o problema N+1.
Posso usar subscriptions com GraphQL gerado por IA?
Sim. Claude Code configura subscriptions com graphql-ws, incluindo autenticação e filtros.
Dá para orquestrar Claude Code e Codex na mesma API GraphQL?
Sim. Com o Orquestra, Claude Code cria resolvers complexos enquanto Codex gera schemas simples e testes. Tudo em paralelo.
Crie sua API GraphQL com agentes hoje
Neste tutorial, você aprendeu a construir uma API GraphQL com TypeGraphQL usando Claude Code e Codex. De schemas a resolvers com DataLoader, cada etapa foi acelerada pelos agentes.
O Orquestra conecta Claude Code, Codex e outros agentes no mesmo canvas infinito no Windows 11. Baixe o Orquestra e comece seu teste grátis de 7 dias.
Links internos recomendados
Pronto para orquestrar seus agentes?
Baixe o Orquestra para Windows 11 e comece a coordenar seus agentes de IA em um canvas infinito. Grátis por 7 dias.