使用事件溯源可以创建 FAT 事件吗?

Is it ok to have FAT events with event sourcing?

我最近一直在 Greg Young EventStore 之上构建一个应用程序作为我的持久层,我一直在思考我应该允许一个事件有多大?

例如,我有一个包含以下字段的英国地址聚合

UK_Address
-BuildingName
-Street
-Locality
-Town 
-Postcode

现在我正在使用 React/Redux 构建 UI,我在想我是否应该创建一个包含上述所有字段的单一 FAT 地址更新事件?

或者我应该为每个不同的字段创建一个事件吗?并在客户端中对它们进行批处理,直到触发 Save 事件? buildingNameUpdated 事件、streetUpdated 事件、localityUpdated 事件。

我不确定答案是否黑白分明 我已经问过了 我真正想知道的是 conditions/constraints 你能用什么来做决定?

should I create a event for each of the different fields?

没有。您的事件的表示是 API 的一部分 -- 因此您希望使用在业务级别而非实施级别有意义的拼写。

Now I'm building the UI using React/Redux and was thinking should I create a single FAT updateAddress Event containing all the above fields?

您不需要限制发送到 UI 的数据以匹配持久存储中的数据。 UI 只是读取模型的缓存表示;没有理由表示需要与事件存储中的形式相同。

考虑 React 模型本身——您的代码更改数据的 "in memory" 表示,然后库计算新的 DOM 并替换它,这反过来会导致浏览器更新其视图,进而导致屏幕上的像素发生变化。

因此,从商店中取出一个胖事件,然后将其分解为 UI 的字段级事件就可以了。从存储中获取多个事件并将它们聚合到 UI 的单个消息中也很好。从事件存储中获取事件并将它们转换为 UI 可以识别的拼写也可以。

Do you have any comment regarding Arien answer regarding keeping fields that need to be consistent together? so regardless of when your snapshop the current state of the world it would be in a valid state?

我不认为这是有道理的,我不确定一般情况下是否可行。

没有意义,因为"valid state"只是一个写模型问题;事件是已经发生的事情,现在来投票决定它们是否有效为时已晚。例如,如果你部署一个新模型,有一个新的不变量,它仍然需要尊重之前发生的事情的历史。因此,您可以为该新模型构建快照,但快照可能不是 "valid"。太可惜了。

鉴于此,我认为担心提交中的每个单独事件是否使快照处于有效状态是没有意义的。

特别是,如果特定交易涉及多个实体,领域语言很可能会为每个实体建议一个事件(我们 "debit cash" 和 "credit accounts receivable")。当然,实体本身能够相互独立地改变——它是维持平衡的集合体。

如果不解,请尝试更容易实现的解决方案。我想 "FAT" 活动会更容易:您最终会花更少的时间参加 implementing/debugging/supporting。

它通常被称为 YAGNI-KISS-Occam 的剃刀原则。

当此数据必须彼此一致时,您必须将所有信息捆绑在一个事件中。

因此,当您更新地址的一个字段时,您可能会得到一个不需要的地址。 当客户端由于最终一致性而没有在某个时间处理所有事件时,就会发生这种情况。

示例: 将地址 (City=1, Street=1, Housenumber=1) 更改为 (City=2, Street=2, Housenumber=2)

当您对 3 个事件执行此操作并且您在阅读时刚刚处理了一个事件时,您可以获得地址:(City=2, Street=1,门牌号=1)。

从理论上讲,我发现一个很好的经验法则是让您的命令和事件反映用户的意图,忠于 DDD。您可以在此处找到有关事件粒度优缺点的很好解释:https://medium.com/@hugo.oliveira.rocha/what-they-dont-tell-you-about-event-sourcing-6afc23c69e9a