Events 事件来源。在哪里生成事件粒度?
我开始从DDD的角度学习EventSourcing。关于EventSourcing的一个声明是,它允许通过重播事件重播应用程序的状态,甚至将应用程序置于以前的状态(过去的状态) 我意识到它增加了复杂性,并且与其他解决方案相比具有优势。我真正关心的是事件发生在哪里。前端还是后端 我将用一个例子来解释它 假设我的应用程序由前端和后端组成,它是关于用户的。用户表示可以如下所示(我将使用JSON表示,尽管问题不是格式或语言特定的): 第一个问题: 假设我从前端创建了一个用户。我的服务器接收以下信息:Events 事件来源。在哪里生成事件粒度?,events,event-sourcing,Events,Event Sourcing,我开始从DDD的角度学习EventSourcing。关于EventSourcing的一个声明是,它允许通过重播事件重播应用程序的状态,甚至将应用程序置于以前的状态(过去的状态) 我意识到它增加了复杂性,并且与其他解决方案相比具有优势。我真正关心的是事件发生在哪里。前端还是后端 我将用一个例子来解释它 假设我的应用程序由前端和后端组成,它是关于用户的。用户表示可以如下所示(我将使用JSON表示,尽管问题不是格式或语言特定的): 第一个问题: 假设我从前端创建了一个用户。我的服务器接收以下信息: {
{
id: 1,
name: "aName",
age: 20,
description: "aDescription"
}
是否应发出以下事件?CreatedEvent、NameChangedEvent、AgeChangedEvent、DescriptionChangedEvent
在这种情况下,前端生成的事件(只有一个)与后端生成的事件(四个)不同
或者应该发出具有所有属性的CreatedEvent?在这种情况下,后端中的事件类似于前端事件(仅一个)
执行更新时也会发生类似的问题。如果我从前端一次更改多个属性,我应该在后端创建一个包含所有这些更改的事件,还是应该将这些更改拆分为多个事件?如果我必须在多个事件中拆分这些更改,我必须检查实体(用户)的当前状态,以检查属性是否已更改。您仍在思考
CRUD
。在CQRS
中,您不设置属性,而是执行命令。那些命令
对您的域模型有意义;它们被发送到聚合
,如果不变量成立,则验证并执行它们;如果没有,它们将被拒绝
我意识到它增加了复杂性,并且与其他解决方案相比具有优势。我真正关心的是事件发生在哪里。前端还是后端
事件由聚合生成,聚合可能在后端执行。前端可能只创建发送到后端的命令
是否应发出以下事件?CreatedEvent、NameChangedEvent、AgeChangedEvent、DescriptionChangedEvent
应该发出什么事件取决于不变量。在您的特定情况下,业务规则允许用户
出生时没有姓名
、年龄
或说明
?如果没有,则必须在CreateUserCommand
中输入所有必需字段,可能还有可选字段,并发出完整的UserWasCreated(id、username、age、description)
。但并不禁止以类似事务的方式发出多个事件,只要它们被持久化(不要求使用事务,要求持久化是原子的:所有事件都被持久化或无)。你应该发出一个或四个大事件?这取决于这些事件的监听者感觉如何,因为它与聚合无关:聚合将接收它发出的内容,并且足以重建其内部状态
事件生成的粒度可能取决于您是否允许像ChangeUserName
这样的粒度命令;如果您允许这样的命令,那么此命令将发出UserNameChanged
事件
我真正关心的是事件发生在哪里。前端还是后端
答案取决于记录簿在哪里。如果事实是由服务本身决定的,那么记录簿就是服务的持久存储——在这些情况下,事件通常在后端生成
如果真相是在服务边界之外(在另一个服务中,或在真实世界中)确定的,那么事件通常是在更接近真相来源的地方生成的
如果我们在做数据输入,我们可能是在描述现实世界中的某些东西,而不是模型控制的东西。对我来说,这听起来像是一个前端用例
假设我从前端创建了一个用户
CRUD动词是一种代码气味——它们通常表示对域的理解肤浅,或者编码人员试图用泛型语言替换特定于域的语言
有时,它们暗示您实际上是在构建一个数据库,而不是一个服务,这暗示您的服务不是记录簿,而是一个持久存储。同样,这种拼写表明前端正在捕获事件,并将它们传递给后端
<>你可能想在你的名字拼写中小心,因为你经常在他们的生命周期中间的实体的快照中工作(EX:“用户”已经存在了20年,但是我们只是在捕捉他们当前的状态,而不是他们的整个历史)。
是否应发出以下事件?CreatedEvent、NameChangedEvent、AgeChangedEvent、DescriptionChangedEvent
不是一般的,不是。变化通常以原子方式表示
执行更新时也会发生类似的问题。如果我从前端一次更改多个属性,我应该在后端创建一个包含所有这些更改的事件,还是应该将这些更改拆分为多个事件
看。编辑通常不是无中生有,但通常有一个可能引起业务兴趣的原因(我们是否更正了错误的输入?现实世界是否发生了变化,使我们以前的数据无效?)。有多个事件包含对同一组字段的更改是完全合理的
{
id: 1,
name: "aName",
age: 20,
description: "aDescription"
}