NestJS下的CQRS实现 - Query部分

本文旨在介绍NestJS下CQRS(命令查询职责分离)的实现。NestJS的确是个强大的NodeJS框架,支持了绝大多数现在流行的技术栈。至于什么是CQRS模式,请大家自行查阅。废话不多说,直接上代码。

1: 新建项目
nest new cqrs-demo

2: 安装CQRS依赖
npm install --save @nestjs/cqrs

3: 添加comments模块
nest g module comments

4: 添加Query相关代码

CQRS的核心,除了Command与Query的分离,还有Controller层与Handler层的解耦。以往的MVC架构中,Controller层会实例化Service,比如UserService,CommentService。Service实例提供了数据库操作逻辑。 这就是Controller与Service的紧耦合。 NestJS的CQRS框架通过QueryBus/CommandBus(.net的CQRS框架中称为Mediator)实现了Controller与事件处理服务的解耦。

且看以下代码
comment.model.ts

export class Comment {
  private readonly id: string;
  constructor(_id: string) {
    this.id = _id;
    console.log(`constructor model - id: ${this.id}`);
  }
}

get-comment.handler.ts

import { IQueryHandler, QueryHandler } from '@nestjs/cqrs';
import { GetCommentQuery } from '../impl';
import { Comment } from '../../models/comment.model';

@QueryHandler(GetCommentQuery)
export class GetCommentsHandler implements IQueryHandler<GetCommentQuery, Comment> {
  
  async execute(query: GetCommentQuery) {
    return new Comment('1');
  }
}

handler/index.ts

import { GetCommentsHandler } from './get-comment.handler';

export const QueryHandlers = [GetCommentsHandler];

get-comment.query.ts

export class GetCommentQuery {}

impl/index.ts

export { GetCommentQuery } from './get-comment.query';

comments.controller.ts

import { Controller, Get } from '@nestjs/common';
import { QueryBus } from '@nestjs/cqrs';
import { Comment } from './models/comment.model';
import { GetCommentQuery } from './queries/impl';

@Controller('comments')
export class CommentsController {
    constructor(
        private readonly queryBus: QueryBus,
      ) {}

    @Get()
    async findAll(): Promise<Comment> {
      return this.queryBus.execute(new GetCommentQuery());
    }
}

comments.module.ts

import { Module } from '@nestjs/common';
import { CqrsModule } from '@nestjs/cqrs';
import { CommentsController } from './comments.controller';
import { QueryHandlers } from './queries/handlers';

@Module({
  imports: [CqrsModule],
  controllers: [CommentsController],
  providers: [
    ...QueryHandlers,
  ],
})
export class CommentsModule {}

用示例图说明如下

Controller与Service之间加入了Mediator(ServiceBus)作为中间人。 在NestJS中,这个中间层通过标签injectable标记的Query类型,代码如下
@QueryHandler(GetCommentQuery)
this.queryBus.execute(new GetCommentQuery());
来寻找对应的Query Handler。

至此,Query的部分说完了,Command的部分会在下一篇文章中再做解释。

参考:
https://docs.nestjs.com/recipes/cqrs

posted @ 2021-09-05 22:02  老胡Andy  阅读(468)  评论(0编辑  收藏  举报