事件什么时候被推送到ES中的事件存储中?

Ger*_*aga 2 architecture domain-driven-design event-driven event-sourcing

我正在尝试一些新概念,事件溯源、微服务以及所有这些范式。

假设我们有以下结构,它代表了基本的事件驱动架构

UI -> API -> EVENTS BROKER ->> MICROSERVICES
Run Code Online (Sandbox Code Playgroud)

我们从客户端(UI)向服务器(API)发出请求,执行一个命令,该命令抛出一个事件,该事件被发布到事件代理中,然后订阅该特定事件的每个服务将启动一个进程,对吗?但是如果我还想实现事件溯源怎么办,看起来可能是这样的,对吗?

UI -> API -> EVENTS BROKER ->> MICROSERVICES
          -> EVENTS STORE
Run Code Online (Sandbox Code Playgroud)

对于这个例子,假设我有一个聚合,它被称为Products“如果在我将事件保存在事件存储中之后,我的业务逻辑说它不应该被允许,因为我现在不允许,也许我们只在特定日期接受新产品”一个月内,但现在我已经存储了该事件

问题本身是,在这种情况下我应该什么时候将事件保存到 EVENT STORE 中?

Lev*_*sey 5

在事件溯源中,基本方法是仅保存有效的事件。因此,在处理命令时,由 API 决定需要发出和保存哪些事件。API 服务应该是唯一决定将哪些事件写入事件存储的东西(并且通过查询事件存储的进程将事件发布到事件代理通常是一个好主意:任何事件都不应该发布到代理(不是由 API 服务写入事件存储)。

现在,如果后来决定不应创建 20 日星期二创建的产品,则无法删除该事件:该产品已创建,这是事实。但是您可以举办一个新活动,也许称为 之类的活动ProductCreationRetracted,其解释是:“哎呀,这个产品不应该被创建”。

一般来说,这将需要修改任何读取或写入Products 事件的内容(除非,例如,通过某种标记,您可以确定它永远不会看到事件ProductCreationRetracted

还值得注意的是,在事件源 DDD 中,确保只有一个进程为给定的聚合根写入事件通常很重要(根据用于从事件派生状态的特定代数,这一要求可能可以放宽:例如,如果代数定义了无冲突的复制数据类型(如果您不知道 CRDT 是什么,则默认假设您不能放松单写入器可能是合理的)。