EventSourcing。生成事件粒度的位置在哪里?

时间:2017-03-13 14:42:39

标签: events event-sourcing

我开始以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,我应该在后端创建一个包含所有这些更改的事件,还是应该在多个事件中拆分这些更改?如果我必须在多个事件中拆分这些更改,我将必须检查实体(用户)的当前状态,以检查该属性是否已更改。

2 个答案:

答案 0 :(得分:2)

你还在考虑CRUD。在CQRS您没有设置属性,您执行Commands。那些Commands对您的域模型有意义;如果不变量持有,它们将被发送到验证并执行它们的Aggregates;如果没有,他们会被拒绝。

  

我意识到它增加的复杂性以及它对其他解决方案的好处。我真正关心的是事件发生的地方。前端还是后端?

事件由Aggregate生成,可能Aggregate在后端执行。前端可能只创建一个发送到后端的命令。

  

是否应发出以下事件? CreatedEvent,NameChangedEvent,AgeChangedEvent,DescriptionChangedEvent

应该发出什么事件取决于你的不变量。在您的具体情况下,业务规则允许User出生时没有nameagedescription?如果没有,那么您必须输入CreateUserCommand所有必填字段,可能还有可选字段,并发出完整的UserWasCreated(id, username, age, description)。但是,只要它们以类似事务的方式持久化就不会发出多个事件(不需要使用事务,要求持久化是原子的:所有事件都是坚持或没有)。你应该发出一个大事件还是四个?这取决于对于那些事件的侦听器感觉如何,因为它与Aggregate无关:Aggregate将接收它发出的内容,并且足以重建其内部状态。

如果您允许像ChangeUserName那样的粒度命令,那么生成事件的精确程度可能取决于...如果您允许这样的命令,则此命令将发出UserNameChanged事件。

答案 1 :(得分:1)

  

我真正关心的是事件发生的地方。前端还是后端?

答案取决于记录簿的位置。如果事实由服务本身决定,那么记录簿就是服务的持久存储 - 在这些情况下,事件通常在后端生成。

如果确定真理是在服务边界之外(在另一个服务中,或在现实世界中),那么事件通常会更接近真实来源。

如果我们正在进行数据输入,我们可能正在描述现实世界中的某些东西,而不是模型所控制的东西。这对我来说听起来像是一个前端用例。

  

想象一下,我从前端

创建了一个用户

CRUD动词是代码气味 - 它们通常表示对域的浅层理解,或者编码器尝试用通用语言替换域特定语言。

有时它们暗示您实际上是在构建数据库,而不是服务,这是您的服务不是记录簿的提示之一,而只是一个耐用的商店。同样,这个拼写表明前端正在捕获事件,并将它们传递到后端。

34;用户"已经存在了20年,但我们只是捕捉他们当前的状态,而不是他们的整个历史。

  

是否应发出以下事件? CreatedEvent,NameChangedEvent,AgeChangedEvent,DescriptionChangedEvent

不一般,没有。变化通常以原子方式表示。

  

执行更新时会发生类似的问题。如果我从前端一次更改了几个proprierties,我应该在后端创建一个包含所有这些更改的事件,还是应该在多个事件中拆分这些更改?

Task Based UI。编辑通常不会来自任何地方,但通常有一个可能对业务感兴趣的原因(我们是否纠正错误的条目?现实世界是否发生变化,使我们以前的数据无效?)。拥有包含对同一组字段的更改的多个事件是完全合理的。