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, чтобы не пропустить новые уроки по современному программированию!