GraphQL став все більш популярним завдяки своїй гнучкості та ефективності при отриманні даних, а NestJS — потужний і прогресивний фреймворк для Node.js — чудово підтримує його. Однією з часто недооценених можливостей GraphQL є підписки (subscriptions), які дозволяють здійснювати передачу даних у реальному часі. Ця можливість може бути надзвичайно корисною для додатків, які вимагають актуальних оновлень даних, таких як чат-додатки, трансляція спортивних результатів, інформація про акції та інше.
У цьому посібнику ми розглянемо, як реалізувати підписки GraphQL в додатку NestJS, використовуючи TypeScript. Ми вивчимо налаштування, приклади коду та деякі найкращі практики для максимального використання цієї можливості.
Що таке підписки GraphQL?
Підписки GraphQL дозволяють клієнтам підписуватися на зміни даних. На відміну від запитів та мутацій, які засновані на принципі запит-відповідь, підписки дозволяють серверам надсилати дані клієнтам, коли відбувається певна подія. Це ґрунтується на WebSockets, які забезпечують канали двостороннього зв'язку через один TCP з'єднання.
Налаштування вашого проєкту NestJS
Спочатку переконайтеся, що у вас встановлені NestJS та необхідні пакети для GraphQL:
npm install @nestjs/graphql graphql apollo-server-express
Якщо вам потрібна підтримка WebSocket, ви можете встановити пакет subscriptions-transport-ws
:
npm install subscriptions-transport-ws graphql-subscriptions
Налаштуйте модуль GraphQL з підтримкою підписок:
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { join } from 'path';
@Module({
imports: [
GraphQLModule.forRoot({
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
subscriptions: {
'graphql-ws': true, // Увімкнути WebSocket підписки
},
}),
],
})
export class AppModule {}
Реалізація підписки
Давайте створимо базову функціональність чату, щоб продемонструвати реалізацію підписок GraphQL в NestJS. Ось як можна налаштувати просту підписку на повідомлення чату:
Крок 1: Описати схему GraphQL
Модифікуйте свою схему GraphQL, щоб включити тип підписки. Ось проста схема, що включає запити, мутації та підписки:
const typeDefs = `
type Message {
id: ID!
content: String!
sender: String!
}
type Query {
messages: [Message]
}
type Mutation {
addMessage(content: String!, sender: String!): Message
}
type Subscription {
messageAdded: Message
}
`;
Крок 2: Налаштування резолвера
Створіть резолвер для обробки підписок. Для реалізації патерну публікація-підписка (publish-subscribe) використовуйте PubSub
:
import { Resolver, Query, Mutation, Args, Subscription } from '@nestjs/graphql';
import { PubSub } from 'graphql-subscriptions';
const pubSub = new PubSub();
@Resolver('Message')
export class MessageResolver {
private messages: any[] = [];
@Query('messages')
getMessages() {
return this.messages;
}
@Mutation('addMessage')
addMessage(
@Args('content') content: string,
@Args('sender') sender: string,
) {
const newMessage = { id: Date.now().toString(), content, sender };
this.messages.push(newMessage);
pubSub.publish('messageAdded', { messageAdded: newMessage });
return newMessage;
}
@Subscription('messageAdded', {
resolve: (value) => value,
})
messageAdded() {
return pubSub.asyncIterator('messageAdded');
}
}
Крок 3: Підключення клієнта
Щоб побачити підписку в дії, вам знадобиться клієнт, який підтримує підписки GraphQL.
Apollo Client є популярним вибором, який ефективно керує підписками за допомогою WebSocket.
Ось простий приклад використання Apollo Client у React:
import { ApolloClient, ApolloProvider, InMemoryCache, HttpLink, split } from '@apollo/client';
import { WebSocketLink } from '@apollo/client/link/ws';
import { getMainDefinition } from '@apollo/client/utilities';
const httpLink = new HttpLink({
uri: 'http://localhost:3000/graphql',
});
const wsLink = new WebSocketLink({
uri: `ws://localhost:3000/graphql`,
options: {
reconnect: true
}
});
const link = split(
({ query }) => {
const definition = getMainDefinition(query);
return definition.kind === 'OperationDefinition' && definition.operation === 'subscription';
},
wsLink,
httpLink,
);
const client = new ApolloClient({
link,
cache: new InMemoryCache()
});
Кращі практики для GraphQL підписок (subscriptions)
- Обмеження витрат даних: Реалізуйте фільтри у своїх підписках, щоб уникнути зайвого обміну даними. Це можна досягти, передаючи аргументи до ваших підписок і виконуючи їх лише тоді, коли умови виконуються.
- Безпека: Завжди аутентифікуйте та авторизуйте підписки (subscriptions), як і будь-який інший веб-запит, щоб запобігти несанкціонованому доступу до WebSocket каналів.
- Масштабованість: При масштабуванні підписок враховуйте використання рішень для управління підписками зі збереженням стану, таких як Redis або Kafka, для ефективного підтримання стану в розподілених системах.
- Обробка помилок: Переконайтеся, що ви коректно обробляєте помилки як на клієнтській, так і на серверній стороні для покращення досвіду користувачів.
Висновок
GraphQL підписки (subscriptions) можуть значно підвищити інтерактивність та відгукливість ваших додатків. З NestJS ви отримуєте потужну платформу, яка спрощує цю реалізацію за допомогою TypeScript, забезпечуючи типову безпеку та кращий досвід розробки.
Це коротке введення до налаштування GraphQL підписок у NestJS охоплює основні кроки, від налаштування до простого прикладу. Коли ви зануритесь глибше, ви знайдете безліч можливостей для використання цих можливостей для створення більш динамічних і реальних додатків.
Перекладено з: Using GraphQL Subscriptions in NestJS: A Comprehensive Guide