Событие после команды в Nest
Запись в массив уже работает, но после неё часто нужен ещё один шаг: счётчик, короткая отметка или другая реакция. Если держать всё в том же обработчике, код разрастается.
Обработчик команды может
после успешной записи
передать объект события
в EventBus.
Отдельный класс с пометкой
@EventsHandler
реализует
IEventHandler
и реагирует, не зная,
кто вызвал команду.
Покажем на примере постов:
export class PostCreatedEvent {
title: string;
constructor(title: string) {
this.title = title;
}
}
Обработчик команды сохраняет строку и публикует событие:
import { CommandHandler, EventBus, ICommandHandler } from '@nestjs/cqrs';
import { CreatePostCommand } from './create-post.command.js';
import { PostCreatedEvent } from './post-created.event.js';
import { PostMemory } from './post.memory.js';
@CommandHandler(CreatePostCommand)
export class CreatePostHandler
implements ICommandHandler<CreatePostCommand>
{
postMemory: PostMemory;
eventBus: EventBus;
constructor(postMemory: PostMemory, eventBus: EventBus) {
this.postMemory = postMemory;
this.eventBus = eventBus;
}
async execute(command: CreatePostCommand) {
const post = { title: command.title };
this.postMemory.posts.push(post);
this.eventBus.publish(
new PostCreatedEvent(command.title),
);
return post;
}
}
Слушатель увеличивает счётчик в своём поле:
import { EventsHandler, IEventHandler } from '@nestjs/cqrs';
import { PostCreatedEvent } from './post-created.event.js';
@EventsHandler(PostCreatedEvent)
export class PostCreatedHandler
implements IEventHandler<PostCreatedEvent>
{
createdCount = 0;
handle() {
this.createdCount += 1;
}
}
Корневой модуль регистрирует слушатель рядом с обработчиком команды:
import { Module } from '@nestjs/common';
import { CqrsModule } from '@nestjs/cqrs';
import { PostController } from './post.controller.js';
import { CreatePostHandler } from './create-post.handler.js';
import { PostCreatedHandler } from './post-created.handler.js';
import { PostMemory } from './post.memory.js';
import { PostService } from './post.service.js';
@Module({
imports: [CqrsModule.forRoot()],
controllers: [PostController],
providers: [
PostMemory,
PostService,
CreatePostHandler,
PostCreatedHandler,
],
})
export class AppModule {}
После записи работника
опубликуйте WorkerCreatedEvent
из CreateWorkerHandler,
а в WorkerCreatedHandler
ведите счётчик в поле класса.