GraphQL API с TypeScript: пошаговый туториал — часть 3

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

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

Начать курс

GraphQL API с TypeScript: пошаговый туториал — часть 3

В предыдущих частях туториала мы разобрали основы создания GraphQL-сервера на TypeScript и научились настраивать простые запросы. В этой финальной части мы углубимся в продвинутые техники: мутации, подписки и обработку ошибок. Если вы изучаете TypeScript для начинающих и хотите освоить современное программирование API, этот материал станет отличным шагом вперёд. Всё обучение построено на практических примерах, которые вы сможете сразу применить в своих проектах.

1. Реализация мутаций с TypeScript

Мутации — это операции изменения данных (создание, обновление, удаление). В GraphQL они обозначаются ключевым словом mutation. Давайте создадим мутацию для добавления нового пользователя.

Сначала определим тип в схеме GraphQL:

type Mutation {
  addUser(name: String!, email: String!): User!
}

Теперь реализуем резолвер на TypeScript. Обратите внимание на строгую типизацию:

import { Resolver, Mutation, Arg } from 'type-graphql';
import { User } from '../entities/User';

@Resolver()
export class UserResolver {
  @Mutation(() => User)
  async addUser(
    @Arg('name') name: string,
    @Arg('email') email: string
  ): Promise<User> {
    const user = new User();
    user.name = name;
    user.email = email;
    await user.save();
    return user;
  }
}

Важно: в TypeScript мы используем декораторы @Mutation и @Arg из библиотеки type-graphql, что делает код чистым и типобезопасным. Это особенно полезно для программирования больших проектов, где важна предсказуемость.

2. Подписки (Subscriptions) для реального времени

Подписки позволяют клиентам получать обновления в реальном времени через WebSocket. В TypeScript их реализация требует дополнительной настройки сервера.

Добавим подписку на новые сообщения:

import { Subscription, Root } from 'type-graphql';

@Resolver()
export class MessageResolver {
  @Subscription(() => Message, {
    topics: 'NEW_MESSAGE',
  })
  newMessage(@Root() message: Message): Message {
    return message;
  }
}

Для публикации события используем pubSub.publish('NEW_MESSAGE', message). Это позволяет создать чат или уведомления в реальном времени. Подписки — мощный инструмент в арсенале программирования, и TypeScript делает их реализацию безопасной благодаря статической типизации.

3. Обработка ошибок и валидация

Грамотная обработка ошибок — ключ к надёжному API. В TypeScript мы можем использовать пользовательские классы ошибок:

import { ApolloError } from 'apollo-server-express';

export class UserInputError extends ApolloError {
  constructor(message: string) {
    super(message, 'USER_INPUT_ERROR');
    Object.defineProperty(this, 'name', { value: 'UserInputError' });
  }
}

В резолверах проверяем входные данные:

@Mutation(() => User)
async createUser(@Arg('email') email: string) {
  if (!email.includes('@')) {
    throw new UserInputError('Invalid email format');
  }
  // ... логика создания
}

Также можно использовать декораторы валидации из class-validator:

import { IsEmail, Length } from 'class-validator';

class CreateUserInput {
  @Length(2, 50)
  name: string;

  @IsEmail()
  email: string;
}

Этот подход особенно рекомендую для TypeScript для начинающих, так как он автоматизирует проверку данных и снижает количество багов.

4. Оптимизация производительности

Для production-проектов важно избегать N+1 проблемы. Используйте DataLoader для батчинга запросов:

import DataLoader from 'dataloader';

const userLoader = new DataLoader(async (ids: number[]) => {
  const users = await User.findByIds(ids);
  return ids.map(id => users.find(u => u.id === id));
});

В резолверах вызывайте userLoader.load(parent.userId) — это объединит множество запросов в один. Такая оптимизация — признак профессионального программирования на TypeScript.

Заключение

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

Продолжайте практиковаться — TypeScript для начинающих становится мощным инструментом только через постоянное применение. В следующей серии статей мы разберём авторизацию и тестирование GraphQL API. Подписывайтесь на обновления PythonLib, чтобы не пропустить новые уроки по современному программированию!

Блоги

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