CQRS - 允许使用事件和其他信息源构建读取模型的依赖关系
我的问题与 CQRS(命令和查询职责分离)和构建读取模型(视图)的机制有关。据我了解,读取模型是由事件处理程序构建的。这些处理程序(也称为反规范化程序)接收域事件并使用这些事件构建不同的数据视图。
特定事件携带有关领域模型中所做更改的信息。我认为这些信息在某些情况下不足以构建视图 - 即在此类事件中缺少未更改的字段、未更改的实体等。
所以我的问题是:
是否允许负责构建读取模型的反规范化器不仅访问事件,而且还允许访问事件?另外:
- 更改直接引用的实体 在事件中?
- 更改聚合根和任何 与该聚合相关的实体?
- 从存储库中获取的任何实体?
- 有什么看法吗?
您对事件处理程序(反规范化器)允许的依赖关系有何看法?
编辑:刚刚为上面的问题添加了简单的示例:
假设以下模型:
AR:ProductOffering * 姓名 * 描述 * 类别 * 价格
AR:客户 * 姓名 * 类型 * 方法:发出的purchaseProduct(productOffering) ProductPurchasedByCustomer 事件
实体:ProductInstance * 顾客 * 产品提供
事件:ProductPurchasedByCustomer * 客户ID * 产品提供 ID
视图:ProductInventoryView * 客户ID * 产品提供 ID * 客户类型 * 产品名称 * 产品类别 * 价格
如何仅使用 ProductPurchasedByCustomer 事件构建 ProductInventoryView?如何编写反规范化器来查看有关 customerType、productOfferingName 等的信息? 我是否应该从不同的视图查找有关 customerType 和 ProductOfferingName 的其他信息?
My question is related to CQRS (Command and Query Responsibility Segregation) and mechanism that builds read model (views). As far as I understand read model is built by event handlers. These handlers (also called denormalizers) receive domain events and use these events to build different views of data.
Specific event carries information about change done in domain model. I think that this information is not sufficient in some cases to build view - i.e. not changed fields, not changed entities are missing in such event etc.
So my question is:
Is it allowed that denormalizer responsible for building read model accesses not only events but also:
- changed entity referenced directly
in event? - changed aggregated root and any
entity related to this aggregate? - any entity fetched from repository?
- any view?
What is your opinion about allowed dependencies for event handlers (denormalizers)?
edit: Just added simple example to the question above:
Suppose the following model:
AR: ProductOffering
* name
* description
* category
* price
AR: Customer
* name
* type
* method: purchaseProduct(productOffering) that emits
ProductPurchasedByCustomer event
entity: ProductInstance
* customer
* productOffering
event: ProductPurchasedByCustomer
* customerId
* productOfferingId
view: ProductInventoryView
* customerId
* productOfferingId
* customerType
* productOfferingName
* productOfferingCategory
* price
How to build ProductInventoryView using only ProductPurchasedByCustomer event? How can I write denormalizer to put into view information about customerType, productOfferingName etc?
Should I lookup additional information about customerType and productOfferingName from different views?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果事件使用者需要更多信息,事件生产者可以提供所需的信息,即使它没有更改。事件外包不应被视为 ORM。请注意,关于如何获取该信息,事情可能会变得棘手,但我们不要让事情变得复杂。如果事件未提供,事件处理程序可以使用读取模型的状态(数据)。但这样做需要您知道是否可以使用以及哪些数据可以使用。它需要您将时间与数据结合起来。消息/事件可能会无序处理。因此,在事件中提供与事件相关的信息要容易得多。在做其他事情之前尝试这样做。不要尝试从特定于您的读取模型的事件处理程序访问您的域,这只是令人讨厌的耦合。最后一件事,聚合可以从其他聚合复制数据以提供事件中所需的数据。请注意,从那时起,您将必须开始思考如何在最初复制数据的聚合中保持数据的新鲜度。可能让你更加困惑......
If an event consumer requires more information, it's okay for an event producer to provide that required information, eventhough it hasn't changed. Eventsourcing should not be treated like an ORM. Mind you things can become tricky with regard to how you get that information, but lets not complicate things (yet). The eventhandlers can use the state (data) of the read model if it's not provided by the event. But doing so requires you to know if and which data you can use. It requires you to couple time to the data. Messages/events are likely to be processed out of order. So, providing information in the event, pertaining to the event, is much easier. Try do that before doing anything else. Don't try to access your domain from the eventhandlers specific to your read model, that's just nasty coupling. One last thing, it's okay for aggregates to copy data from other aggregates to provide the data you need in your events. Mind you that from then on you'll have to start thinking on how to keep that data fresh in the aggregates that copied it in the first place. Probably confused you some more ...
据我的理解:
不
不
不
任何与事件无关
是的
是的
,因为反规范化器应该对域存储库一无所知,并且仅更新相关报告。
如果报告看起来不相关但必须更新,那就是代码味道 - 可能您设计的模型/报告不正确。
According to my understanding:
no
no
no
no
yes
yes
because denormalizer is supposed to know nothing about domain repository and update related reports only.
if it seems that report is unrelated but it must be updated, that's a code smell - likely You are designing Your model/reports incorrectly.