GraphQL библиотека TypeScript: полное руководство по инструментам

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

GraphQL библиотека TypeScript: современный подход к API

GraphQL — это язык запросов для API, который позволяет клиентам запрашивать только необходимые данные. В связке с TypeScript он даёт мощную систему типов, обеспечивающую безопасность и автодополнение. На pythonlib.ru мы разберём ключевую библиотеку для работы с GraphQL в TypeScript — type-graphql, а также альтернативы.

Почему TypeScript + GraphQL?

TypeScript добавляет статическую типизацию, что критически важно для крупных проектов. GraphQL-схема, описанная через TypeScript-классы, становится единым источником правды: изменения в коде автоматически синхронизируются с API. Это исключает расхождения между документацией и реальным поведением сервера.

Основная библиотека: TypeGraphQL

type-graphql — это фреймворк для создания GraphQL API на TypeScript с использованием декораторов. Он следует принципу code-first: вы определяете схему через код, а не через SDL (Schema Definition Language).

Установка

npm install type-graphql graphql reflect-metadata

Добавьте в tsconfig.json:

{
  "emitDecoratorMetadata": true,
  "experimentalDecorators": true
}

Пример: определение типа и резолвера

Создадим простую модель пользователя и резолвер для получения данных.

import { ObjectType, Field, ID, Resolver, Query } from "type-graphql";

@ObjectType()
class User {
  @Field(() => ID)
  id: number;

  @Field()
  name: string;

  @Field({ nullable: true })
  email?: string;
}

@Resolver()
class UserResolver {
  @Query(() => [User])
  users(): User[] {
    return [
      { id: 1, name: "Анна", email: "anna@example.com" },
      { id: 2, name: "Борис", email: null }
    ];
  }
}

Сборка и запуск сервера

import { buildSchema } from "type-graphql";
import { ApolloServer } from "@apollo/server";
import { startStandaloneServer } from "@apollo/server/standalone";

async function main() {
  const schema = await buildSchema({
    resolvers: [UserResolver]
  });

  const server = new ApolloServer({ schema });
  const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });
  console.log(`Сервер запущен: ${url}`);
}

main();

Альтернативные библиотеки

  • NestJS + GraphQL — интеграция с популярным фреймворком. Использует @nestjs/graphql на основе type-graphql.
  • GraphQL Nexus — code-first библиотека без декораторов, использует цепочки методов.
  • Pothos GraphQL — современная code-first библиотека с отличной поддержкой TypeScript.

Продвинутые возможности TypeGraphQL

Аргументы и мутации

import { Arg, Mutation } from "type-graphql";

@Resolver()
class UserResolver {
  @Mutation(() => User)
  createUser(@Arg("name") name: string, @Arg("email") email: string): User {
    return { id: 3, name, email };
  }
}

Валидация с помощью class-validator

import { Length, IsEmail } from "class-validator";
import { InputType, Field } from "type-graphql";

@InputType()
class CreateUserInput {
  @Field()
  @Length(2, 30)
  name: string;

  @Field()
  @IsEmail()
  email: string;
}

Авторизация через middleware

import { UseMiddleware } from "type-graphql";

function AuthMiddleware(): MiddlewareFn {
  return async ({ context }, next) => {
    if (!context.user) throw new Error("Не авторизован");
    return next();
  };
}

@Resolver()
class UserResolver {
  @Query(() => User)
  @UseMiddleware(AuthMiddleware)
  me(): User {
    return { id: 1, name: "Текущий пользователь", email: "user@example.com" };
  }
}

Интеграция с базами данных

TypeGraphQL отлично работает с ORM. Пример с TypeORM:

import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";

@Entity()
class UserEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column({ nullable: true })
  email: string;
}

// В резолвере используем репозиторий
@Resolver()
class UserResolver {
  constructor(private userRepo: Repository<UserEntity>) {}

  @Query(() => [User])
  async users(): Promise<User[]> {
    return this.userRepo.find();
  }
}

Сравнение подходов: code-first vs schema-first

  • Code-first (TypeGraphQL): схема генерируется из

Рекомендаций