使用Note API示例在Nestjs中实现CQRS模式
#typescript #node #nestjs #cqrs

CQRS Pattern in NestJS

在软件体系结构的世界中,设计可扩展,可维护和高效的系统是最重要的问题。为实现这些目标而获得吸引力的一种建筑模式是命令查询责任隔离(CQRS)模式。 CQRS对于需要复杂的数据操作和查询的应用程序特别有用。在本文中,我们将通过创建Note API示例来探讨如何在Nestjs应用程序中实现CQRS模式。

了解CQRS模式

cqrs是一种架构模式,可将处理和写入操作的责任分开。它认识到,阅读数据的要求通常与编写数据的要求不同。通过隔离这些责任,CQR允许独立优化读写路径,从而提高了性能,可伸缩性和可维护性。

在基于CQRS的体系结构中,有两个主要组件:命令侧和查询侧。

  • 命令侧:该方面负责处理写操作,例如创建,更新和删除数据。它使用命令来触发应用程序状态的更改。
  • 查询方:此方面负责处理读取操作。它着重于以优化查询和显示的格式传递数据,而不必担心基础数据存储或操纵逻辑。

在Nestjs中实现CQR

Nestjs是一个流行的Node.js框架,为构建可扩展和可维护的服务器端应用程序提供了坚实的基础。要在Nestjs中实现CQRS模式,我们将使用 @nestjs/cqrs软件包,该软件包提供了用于管理命令,事件和查询的工具和装饰器。

让我们使用Nestjs中的CQR浏览Note API的实现。

步骤1:设置项目

首先,如果您已经没有:
创建一个新的Nestjs项目

nest new note-api-cqrs

导航到项目目录:

cd note-api-cqrs

步骤2:安装依赖项

安装CQR和其他功能所需的依赖项:

npm install --save @nestjs/cqrs

步骤3:创建命令,事件和查询

在CQRS中,命令表示修改应用程序状态的操作,事件表示过去发生的事物,查询代表信息的请求。让我们为我们的Note API创建这些组件。

创建一个音符模块:

nest generate module notes

步骤4:创建命令

在注释模块中,创建create not.command.ts文件并实现创建注释命令。

export class CreateNoteCommand {
  constructor(public readonly title: string, public readonly content: string) {}
}

步骤5:创建查询

在注释模块中,创建一个get-notes.query.ts文件并实现get notes查询。

export class GetNotesQuery {}

步骤6:实施命令处理程序

创建一个create-note.handler.ts文件并实现命令处理程序:

import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
import { CreateNoteCommand } from './create-note.command';
import { NoteCreatedEvent } from '../events/note-created.event';

@CommandHandler(CreateNoteCommand)
export class CreateNoteHandler implements ICommandHandler<CreateNoteCommand> {
  async execute(command: CreateNoteCommand): Promise<void> {
    // Here, you can perform the necessary logic to create a new note
    const { title, content } = command;

    // Simulate note creation
    const noteId = Math.random().toString(36).substring(7);

    // Emit a NoteCreatedEvent
    const event = new NoteCreatedEvent(noteId, title, content);
    event.commit();
  }
}

步骤7:实施查询处理程序

创建aget-notes.handler.ts文件并实现查询处理程序:

import { IQueryHandler, QueryHandler } from '@nestjs/cqrs';
import { GetNotesQuery } from './get-notes.query';

@QueryHandler(GetNotesQuery)
export class GetNotesHandler implements IQueryHandler<GetNotesQuery> {
  async execute(query: GetNotesQuery): Promise<any> {
    // Here, you can retrieve notes data for querying
    // For demonstration purposes, let's return a mock list of notes
    return [
      { id: 1, title: 'Note 1', content: 'Content of note 1' },
      { id: 2, title: 'Note 2', content: 'Content of note 2' },
    ];
  }
}

步骤8:将所有内容连接在一起

在notes.module.ts文件中,配置CQRS模块以使用命令处理程序和查询处理程序:

import { Module } from '@nestjs/common';
import { CqrsModule } from '@nestjs/cqrs';
import { NotesController } from './notes.controller';
import { CreateNoteHandler } from './commands/create-note.command';
import { NoteCreatedHandler } from './events/note-created.event';
import { GetNotesHandler } from './queries/get-notes.query';

@Module({
  imports: [CqrsModule],
  controllers: [NotesController],
  providers: [CreateNoteHandler, GetNotesHandler],
})
export class NotesModule {}

步骤9:创建笔记控制器

在notes.controller.ts文件中,创建一个控制器来处理API请求:

import { Controller, Get, Post, Body } from '@nestjs/common';
import { CommandBus, QueryBus } from '@nestjs/cqrs';
import { CreateNoteCommand } from './commands/create-note.command';
import { GetNotesQuery } from './queries/get-notes.query';

@Controller('notes')
export class NotesController {
  constructor(
    private readonly commandBus: CommandBus,
    private readonly queryBus: QueryBus,
  ) {}

  @Post()
  async createNote(@Body() body: { title: string, content: string }): Promise<void> {
    const { title, content } = body;
    await this.commandBus.execute(new CreateNoteCommand(title, content));
  }

  @Get()
  async getNotes(): Promise<any[]> {
    return this.queryBus.execute(new GetNotesQuery());
  }
}

步骤10:运行应用程序

最后,启动Nestjs应用程序:

npm run start:dev

带有CQRS模式的Note API现在正在启动并运行!您可以使用Curl,Postman或其他API测试工具等工具与API进行交互。

结论

CQRS模式是通过隔离读写操作来实现应用程序中关注点的有力方法。借助 @nestjs/cqrs软件包,在Nestjs应用程序中实现CQRS模式变得很简单。通过使用命令和查询,您可以有效处理复杂的数据操纵和查询方案,同时保持可扩展性和可维护性。

这是一个示例项目存储库的链接,以对本文讨论的概念进行更具体的演示:Github Repo