Шина команд в Nest
Для одной операции записи отдельный сервис только чтобы передать объект в шину выглядит лишним. Контроллер и так собирается фреймворком, и общая шина уже доступна в приложении.
CommandBus
можно внедрить прямо
в контроллер: метод страницы
создаёт команду и передаёт
её шине, а обработчик
по-прежнему меняет память.
Такой приём уместен,
когда прослойка не добавляет
своей логики.
Покажем на примере постов:
import { Body, Controller, Post } from '@nestjs/common';
import { CommandBus } from '@nestjs/cqrs';
import { CreatePostCommand } from './create-post.command.js';
@Controller('posts')
export class PostController {
commandBus: CommandBus;
constructor(commandBus: CommandBus) {
this.commandBus = commandBus;
}
@Post()
create(@Body('title') title: string) {
return this.commandBus.execute(
new CreatePostCommand(title),
);
}
}
Обработчик команды остаётся единственным местом записи в массив:
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
import { CreatePostCommand } from './create-post.command.js';
import { PostMemory } from './post.memory.js';
@CommandHandler(CreatePostCommand)
export class CreatePostHandler
implements ICommandHandler<CreatePostCommand>
{
postMemory: PostMemory;
constructor(postMemory: PostMemory) {
this.postMemory = postMemory;
}
async execute(command: CreatePostCommand) {
const post = { title: command.title };
this.postMemory.posts.push(post);
return post;
}
}
Корневой модуль больше не подключает сервис-прокладку, только шину, память и обработчик:
import { Module } from '@nestjs/common';
import { CqrsModule } from '@nestjs/cqrs';
import { PostController } from './post.controller.js';
import { CreatePostHandler } from './create-post.handler.js';
import { PostMemory } from './post.memory.js';
@Module({
imports: [CqrsModule.forRoot()],
controllers: [PostController],
providers: [PostMemory, CreatePostHandler],
})
export class AppModule {}
Отправляйте
CreateWorkerCommand
из WorkerController
через CommandBus
без отдельного сервиса,
оставив запись в
CreateWorkerHandler.