@hestjs/cqrs
HestJS CQRS - Command Query Responsibility Segregation module for HestJS
安装
npm install @hestjs/cqrs
基本用法
1. 初始化CQRS模块
import { CqrsModule } from "@hestjs/cqrs";
CqrsModule.forRoot();
CqrsModule.forRoot({
});
2. 创建Command
import { Command } from "@hestjs/cqrs";
export class CreateUserCommand extends Command<string> {
constructor(
public readonly name: string,
public readonly email: string
) {
super();
}
}
3. 创建Command Handler
import { CommandHandler, ICommandHandler } from "@hestjs/cqrs";
import { CreateUserCommand } from "./create-user.command";
@CommandHandler(CreateUserCommand)
export class CreateUserHandler
implements ICommandHandler<CreateUserCommand, string>
{
async execute(command: CreateUserCommand): Promise<string> {
console.log(`Creating user: ${command.name} (${command.email})`);
return "user-id-123";
}
}
4. 创建Query
import { Query, IQueryResult } from "@hestjs/cqrs";
export class GetUserQuery extends Query<GetUserResult> {
constructor(public readonly userId: string) {
super();
}
}
export class GetUserResult implements IQueryResult {
constructor(
public readonly id: string,
public readonly name: string,
public readonly email: string
) {}
}
5. 创建Query Handler
import { QueryHandler, IQueryHandler } from "@hestjs/cqrs";
import { GetUserQuery, GetUserResult } from "./get-user.query";
@QueryHandler(GetUserQuery)
export class GetUserHandler
implements IQueryHandler<GetUserQuery, GetUserResult>
{
async execute(query: GetUserQuery): Promise<GetUserResult> {
return new GetUserResult(query.userId, "John Doe", "john@example.com");
}
}
6. 创建Event
import { Event } from "@hestjs/cqrs";
export class UserCreatedEvent extends Event {
constructor(
public readonly userId: string,
public readonly name: string,
public readonly email: string
) {
super(userId);
}
}
7. 创建Event Handler
import { EventsHandler, IEventHandler } from "@hestjs/cqrs";
import { UserCreatedEvent } from "./user-created.event";
@EventsHandler(UserCreatedEvent)
export class UserCreatedHandler implements IEventHandler<UserCreatedEvent> {
async handle(event: UserCreatedEvent): Promise<void> {
console.log(`User created: ${event.name} (${event.email})`);
}
}
8. 在控制器中使用
import { Controller, Post } from "@hestjs/core";
import { CommandBus, QueryBus, EventBus } from "@hestjs/cqrs";
import { CreateUserCommand } from "./commands/create-user.command";
import { GetUserQuery } from "./queries/get-user.query";
import { UserCreatedEvent } from "./events/user-created.event";
@Controller("/users")
export class UserController {
constructor(
private readonly commandBus: CommandBus,
private readonly queryBus: QueryBus,
private readonly eventBus: EventBus
) {}
@Post()
async createUser(data: { name: string; email: string }) {
const command = new CreateUserCommand(data.name, data.email);
const userId = await this.commandBus.execute(command);
const event = new UserCreatedEvent(userId, data.name, data.email);
await this.eventBus.publish(event);
return { userId };
}
@Get("/:id")
async getUser(id: string) {
const query = new GetUserQuery(id);
return await this.queryBus.execute(query);
}
}
9. 注册处理器
import { CqrsModule } from "@hestjs/cqrs";
import { CreateUserHandler } from "./handlers/create-user.handler";
import { GetUserHandler } from "./handlers/get-user.handler";
import { UserCreatedHandler } from "./handlers/user-created.handler";
CqrsModule.forRoot();
const cqrsModule = CqrsModule.getInstance();
cqrsModule.registerHandler(CreateUserHandler);
cqrsModule.registerHandler(GetUserHandler);
cqrsModule.registerHandler(UserCreatedHandler);
await cqrsModule.onApplicationBootstrap();
10. Saga (长期运行的流程)
import { Saga, ICommand } from "@hestjs/cqrs";
import { UserCreatedEvent } from "./events/user-created.event";
import { SendWelcomeEmailCommand } from "./commands/send-welcome-email.command";
@Saga()
export class UserSaga {
async onUserCreatedEvent(event: UserCreatedEvent): Promise<ICommand[]> {
return [new SendWelcomeEmailCommand(event.userId, event.email)];
}
}
API 参考
装饰器
@CommandHandler(command) - 标记命令处理器
@QueryHandler(query) - 标记查询处理器
@EventsHandler(...events) - 标记事件处理器
@Saga() - 标记Saga
基类
Command<T> - 命令基类,T为返回类型
Query<T> - 查询基类,T为结果类型
Event - 事件基类
总线
CommandBus - 命令总线
QueryBus - 查询总线
EventBus - 事件总线
接口
ICommandHandler<TCommand, TResult> - 命令处理器接口
IQueryHandler<TQuery, TResult> - 查询处理器接口
IEventHandler<TEvent> - 事件处理器接口
ISaga<TEvent> - Saga接口
许可证
MIT