Subscriptions
Before reading this it is recommended to read the nestjs graphql subscriptions docs.
nestjs-query
includes out of the box subscription support. When enabling subscriptions the following subscriptions will be created
created{ObjectName}
- published when thecreateOne
orcreateMany
mutation is called.updatedOne{ObjectName}
- published when theupdateOne
mutation is called.updatedMany{ObjectName}
- published whenupdateMany
mutation is called.deletedOne{ObjectName}
- published when thedeleteOne
mutation is called.deletedMany{ObjectName}
- published whendeleteMany
mutation is called.
Enabling Subscriptions
You can enable subscriptions through the auto-generated resolver using the NestjsQueryGraphQLModule
or by manually defining your resolver.
In both cases you need to set the enableSubscriptions
option to true
.
In the below example the following subscriptions will be exposed.
createdTodoItem
- published when thecreateOne
orcreateMany
mutation is called.updatedOneTodoItem
- published when theupdateOne
mutation is called.updatedManyTodoItems
- published whenupdateMany
mutation is called.deletedOneTodoItem
- published when thedeleteOne
mutation is called.deletedManyTodoItems
- published whendeleteMany
mutation is called.
- NestjsQueryGraphQLModule
- CRUDResolver
import { NestjsQueryGraphQLModule } from '@ptc-org/nestjs-query-graphql';
import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
import { Module } from '@nestjs/common';
import { TodoItemInputDTO } from './todo-item.input';
import { TodoItemDTO } from './todo-item.dto';
import { TodoItemEntity } from './todo-item.entity';
@Module({
imports: [
NestjsQueryGraphQLModule.forFeature({
imports: [NestjsQueryTypeOrmModule.forFeature([TodoItemEntity])],
resolvers: [{
DTOClass: TodoItemDTO,
EntityClass: TodoItemEntity,
CreateDTOClass: TodoItemInputDTO,
UpdateDTOClass: TodoItemInputDTO,
enableSubscriptions: true,
}],
}),
],
})
export class TodoItemModule {}
When manually defining your resolver you must also provide a readonly pubSub
property. In this the default PubSub
implementation is injected.
import { QueryService, InjectQueryService } from '@ptc-org/nestjs-query-core';
import { CRUDResolver, InjectPubSub } from '@ptc-org/nestjs-query-graphql';
import { Resolver } from '@nestjs/graphql';
import { PubSub } from 'graphql-subscriptions';
import { TodoItemInputDTO } from './todo-item.input';
import { TodoItemDTO } from './todo-item.dto';
import { TodoItemEntity } from './todo-item.entity';
@Resolver()
export class TodoItemResolver extends CRUDResolver(TodoItemDTO, {
CreateDTOClass: TodoItemInputDTO,
UpdateDTOClass: TodoItemInputDTO,
enableSubscriptions: true,
}) {
constructor(
@InjectQueryService(TodoItemEntity) readonly service: QueryService<TodoItemEntity>,
@InjectPubSub() readonly pubSub: PubSub
) {
super(service);
}
}
Enabling/Disabling Individual Subscriptions
You also have the option to selectively enable or disable individual subscriptions.
In this example the updatedMany
and deletedMany
subscriptions are disabled.
- NestjsQueryGraphQLModule
- CRUDResolver
import { NestjsQueryGraphQLModule } from '@ptc-org/nestjs-query-graphql';
import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
import { Module } from '@nestjs/common';
import { TodoItemInputDTO } from './dto/todo-item-input.dto';
import { TodoItemUpdateDTO } from './dto/todo-item-update.dto';
import { TodoItemDTO } from './dto/todo-item.dto';
import { TodoItemEntity } from './todo-item.entity';
@Module({
imports: [
NestjsQueryGraphQLModule.forFeature({
imports: [NestjsQueryTypeOrmModule.forFeature([TodoItemEntity])],
resolvers: [
{
DTOClass: TodoItemDTO,
EntityClass: TodoItemEntity,
CreateDTOClass: TodoItemInputDTO,
UpdateDTOClass: TodoItemUpdateDTO,
enableSubscriptions: true,
update: { many: { enableSubscriptions: false } },
delete: { many: { enableSubscriptions: false } },
},
],
}),
],
})
export class TodoItemModule {}
import { QueryService, InjectQueryService } from '@ptc-org/nestjs-query-core';
import { CRUDResolver, InjectPubSub } from '@ptc-org/nestjs-query-graphql';
import { Resolver } from '@nestjs/graphql';
import { PubSub } from 'graphql-subscriptions';
import { TodoItemInputDTO } from './todo-item.input';
import { TodoItemDTO } from './todo-item.dto';
import { TodoItemEntity } from './todo-item.entity';
@Resolver()
export class TodoItemResolver extends CRUDResolver(TodoItemDTO, {
CreateDTOClass: TodoItemInputDTO,
UpdateDTOClass: TodoItemInputDTO,
enableSubscriptions: true,
update: { many: { enableSubscriptions: false } },
delete: { many: { enableSubscriptions: false } },
}) {
constructor(
@InjectQueryService(TodoItemEntity) readonly service: QueryService<TodoItemEntity>,
@InjectPubSub() readonly pubSub: PubSub
) {
super(service);
}
}
Filtering Subscriptions
The created
, updatedOne
and deletedOne
subscriptions all for a Filter
to be passed in filter for events that match the criteria
The filter your provide is the same type that is used when querying for records.
For example to filter for all created TodoItems
where the like starts with Foo
and is completed, you could do the following.
subscription {
createdTodoItem(
input: { filter: { title: { like: "Foo%" }, completed: { is: true } } }
) {
id
title
description
completed
created
updated
}
}
Custom PubSub Provider
You can override the default PubSub
implementation by creating your own provider and providing it to nestjs-query
.
Below is an example provider.
import { pubSubToken } from '@ptc-org/nestjs-query-graphql';
import { RedisPubSub } from 'graphql-redis-subscriptions';
import Redis from 'ioredis';
import { Provider } from '@nestjs/common';
export class RedisPubSubProvider {
static provider(): Provider {
return {
provide: pubSubToken(),
useValue: new RedisPubSub({
publisher: new Redis(),
subscriber: new Redis(),
}),
};
}
}
In order to let nestjs-query
know about the provider you can set the pubSub
option.
import { NestjsQueryGraphQLModule } from '@ptc-org/nestjs-query-graphql';
import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
import { Module } from '@nestjs/common';
import { TodoItemInputDTO } from './dto/todo-item-input.dto';
import { TodoItemUpdateDTO } from './dto/todo-item-update.dto';
import { TodoItemDTO } from './dto/todo-item.dto';
import { TodoItemEntity } from './todo-item.entity';
import { RedisPubSubProvider } from '../redis-pub-sub.provider';
@Module({
imports: [
NestjsQueryGraphQLModule.forFeature({
imports: [NestjsQueryTypeOrmModule.forFeature([TodoItemEntity])],
pubSub: RedisPubSubProvider.provider(),
resolvers: [
{
DTOClass: TodoItemDTO,
EntityClass: TodoItemEntity,
CreateDTOClass: TodoItemInputDTO,
UpdateDTOClass: TodoItemUpdateDTO,
enableSubscriptions: true,
},
],
}),
],
})
export class TodoItemModule {}