我开始以DDD的角度学习EventSourcing。关于EventSourcing的一个主张是它允许通过重放事件来重放应用程序的状态,甚至将应用程序置于之前的状态(过去的状态)。
我意识到它增加的复杂性以及它对其他解决方案的好处。我真正关心的是事件发生的地方。前端还是后端?
我将用一个例子来解释它。
想象一下,我的应用程序由前端和后端组成,是关于用户的。用户表示可以如下(我将使用JSON进行表示,尽管问题不是格式,也不是语言特定的):
{
id: int,
name: string,
age: int,
description: string
}
第一个问题:
想象一下,我从前端创建了一个用户。我的服务器收到以下内容:
{
id: 1,
name: "aName",
age: 20,
description: "aDescription"
}
是否应发出以下事件? CreatedEvent,NameChangedEvent,AgeChangedEvent,DescriptionChangedEvent
在这种情况下,前端生成的事件(只有一个)与后端(四个)生成的事件不同。
或者应该发出具有所有特性的CreatedEvent?在这种情况下,后端的事件类似于前端的事件(只有一个)
执行更新时会发生类似的问题。如果我从前端一次更改了几个proprierties,我应该在后端创建一个包含所有这些更改的事件,还是应该在多个事件中拆分这些更改?如果我必须在多个事件中拆分这些更改,我将必须检查实体(用户)的当前状态,以检查该属性是否已更改。
答案 0 :(得分:2)
你还在考虑CRUD
。在CQRS
您没有设置属性,您执行Commands
。那些Commands
对您的域模型有意义;如果不变量持有,它们将被发送到验证并执行它们的Aggregates
;如果没有,他们会被拒绝。
我意识到它增加的复杂性以及它对其他解决方案的好处。我真正关心的是事件发生的地方。前端还是后端?
事件由Aggregate生成,可能Aggregate在后端执行。前端可能只创建一个发送到后端的命令。
是否应发出以下事件? CreatedEvent,NameChangedEvent,AgeChangedEvent,DescriptionChangedEvent
应该发出什么事件取决于你的不变量。在您的具体情况下,业务规则允许User
出生时没有name
,age
或description
?如果没有,那么您必须输入CreateUserCommand
所有必填字段,可能还有可选字段,并发出完整的UserWasCreated(id, username, age, description)
。但是,只要它们以类似事务的方式持久化就不会发出多个事件(不需要使用事务,要求持久化是原子的:所有事件都是坚持或没有)。你应该发出一个大事件还是四个?这取决于对于那些事件的侦听器感觉如何,因为它与Aggregate无关:Aggregate将接收它发出的内容,并且足以重建其内部状态。
如果您允许像ChangeUserName
那样的粒度命令,那么生成事件的精确程度可能取决于...如果您允许这样的命令,则此命令将发出UserNameChanged
事件。
答案 1 :(得分:1)
我真正关心的是事件发生的地方。前端还是后端?
答案取决于记录簿的位置。如果事实由服务本身决定,那么记录簿就是服务的持久存储 - 在这些情况下,事件通常在后端生成。
如果确定真理是在服务边界之外(在另一个服务中,或在现实世界中),那么事件通常会更接近真实来源。
如果我们正在进行数据输入,我们可能正在描述现实世界中的某些东西,而不是模型所控制的东西。这对我来说听起来像是一个前端用例。
想象一下,我从前端
创建了一个用户
CRUD动词是代码气味 - 它们通常表示对域的浅层理解,或者编码器尝试用通用语言替换域特定语言。
有时它们暗示您实际上是在构建数据库,而不是服务,这是您的服务不是记录簿的提示之一,而只是一个耐用的商店。同样,这个拼写表明前端正在捕获事件,并将它们传递到后端。
34;用户"已经存在了20年,但我们只是捕捉他们当前的状态,而不是他们的整个历史。
是否应发出以下事件? CreatedEvent,NameChangedEvent,AgeChangedEvent,DescriptionChangedEvent
不一般,没有。变化通常以原子方式表示。
执行更新时会发生类似的问题。如果我从前端一次更改了几个proprierties,我应该在后端创建一个包含所有这些更改的事件,还是应该在多个事件中拆分这些更改?
见Task Based UI。编辑通常不会来自任何地方,但通常有一个可能对业务感兴趣的原因(我们是否纠正错误的条目?现实世界是否发生变化,使我们以前的数据无效?)。拥有包含对同一组字段的更改的多个事件是完全合理的。