在 NestJS CQRS 配方中处理“事件源”的首选方式

use*_*198 6 cqrs node.js event-sourcing typescript nestjs

我一直在尝试找出在使用 NestJS CQRS 配方 ( https://docs.nestjs.com/recipes/cqrs )时进行“事件溯源”的首选方式。

在过去的几周里,我一直在研究 NestJS 框架,并且喜欢它的各个方面。除了文档,它们在某些方面非常薄。

要么 NestJS 对如何实现“事件溯源”没有真正的意见,要么我遗漏了一些明显的东西。

我的主要问题是:保持事件本身的最简单方法是什么?

现在,我的事件看起来非常基本:

import { IEvent } from '@nestjs/cqrs';

export class BookingChangedTitleEvent implements IEvent {
    constructor(
        public readonly bookingId: string,
        public readonly title: string) {}
}
Run Code Online (Sandbox Code Playgroud)

我最初的想法是使用 TypeORM ( https://docs.nestjs.com/recipes/sql-typeorm ) 并使我的每个事件不仅实现IEvent,而且还使其继承 TypeORM @Entity()

但是,每个事件都有一个表 (SQL) 或集合 (NoSQL),因此无法读取发生在单个聚合上的所有事件。我错过了什么吗?

另一种方法是将每个事件转储到 JSON,这听起来很简单。但是我将如何IEvent从数据库加载对象类呢?(听起来我正在实施我自己的 ORM)

小智 3

所以我正在做类似的事情并使用 postgres,它确实支持 TypeORM 白话(参考)中的 json ('simple-json')。无论好坏,我的事件实体如下所示:

@Entity()
export class MyEvent {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  name: string;

  @Column('simple-json')
  data: object;

  @CreateDateColumn({type: 'timestamp'})
  created_at: Date;
}
Run Code Online (Sandbox Code Playgroud)

需要注意的是,我仅将持久事件用于审计跟踪以及我尚未构建的潜在预测的灵活性。您绝对可以使用 TypeORM 在 postgres 中查询 JSON,例如。.where('my_event.data ::jsonb @> :data', {data: {someDataField: 2}}),但我的理解是查询事件以获取当前状态有点错过了 CQRS 的意义。最好在新的投影表中构建聚合或更新一个巨大的投影。

我对我目前坚持活动的方式感到满意,但它肯定不是干的。我认为用一个共同的扩展基类saveEvent或使用在其构造函数中获取存储库的 EventHandlerFactory 类会更干净一些,而不是将存储库注入到每个处理程序中。

也许有人有一些好的想法?