简单 "CRUD" 读取 Axon 聚合体
Simple "CRUD" read on Axon aggregate
在没有 AxonServer 的情况下,在 REST-Axon 程序中对聚合执行基本 GET 操作的最简单方法是什么?
- 我有一个带有聚合 FooAggregate 的简单 springboot Axon-and-REST 应用程序。
- 我用
POST /foos
创建了 Foo,它在命令网关等上发送命令
- 我通过实际查询
GET /foo-summaries
来查询所有 Foos 的列表,这会在查询网关上触发查询 objects,并且 returns where FooSummary objects,其中FooSummary 是我在侦听 FooCreated 和 FooUpdated 事件的投影中创建的 JPA 实体。
到目前为止所有标准的东西。但是简单的 GET /foos/{id}
呢?
那 URL /foo/{id}
是我想要 return 在位置 header 从 POST /foos
我想要 this GET 到 return all 我的 Foo 的详细信息 - 所有这些都被建模为 FooAggregate 的属性( FooSummary 可能 return 列表的子集)
现在,Axon documentation suggests this:
Standard repositories store the actual state of an Aggregate. Upon each change, the new state will overwrite the old. This makes it possible for the query components of the application to use the same information the command component also uses. This could, depending on the type of application you are creating, be the simplest solution.
但这仅适用于我使用 state-stored 聚合的情况,对吧?我正在使用 Event-Sourced 聚合和 JPA 事件存储。
我的选择似乎是:
忘记 event-sourcing 并使用 stored-state 聚合方法,正如建议的那样 'simplest' 方法(我没有任何特定需要事件源我的聚合 - 虽然我 肯定是 事件源我的投影
在我的 FooSummary 投影 table 中保留完整的详细信息,并使用与 GET /foo-summaries
略有不同的查询将 GET /foo/{id}
定向到那里(或者,只需调用它GET /foos
和 return 摘要)
创建一个单独的“投影”来存储完整的 Foo 详细信息。这将 实际上与我们在 state-stored 聚合 中使用的相同,因此看起来有点奇怪。
第四个选项 - 这个问题的原因?
回答我自己的问题,但实际上答案来自与 Axon 的 Christian 的讨论。 (在接受我自己的答案之前,将把它打开几天以便获得更好的答案:))
我的选项 #2 和 #3 是正确的答案:差异取决于我的“摘要”预测与“详细”预测的不同程度。如果它们足够接近,选项 #2,如果它们足够不同,则选项 #3。
选项 #1 并不理想,因为即使我们出于其他原因使用状态存储,基于状态存储的查询也会打破 CQRS 中 'S' 的隔离:它使得我们的查询模型依赖于我们的命令模型,当我们的模型变得更复杂时,这可能会导致问题。
(感谢克里斯蒂安)
在没有 AxonServer 的情况下,在 REST-Axon 程序中对聚合执行基本 GET 操作的最简单方法是什么?
- 我有一个带有聚合 FooAggregate 的简单 springboot Axon-and-REST 应用程序。
- 我用
POST /foos
创建了 Foo,它在命令网关等上发送命令 - 我通过实际查询
GET /foo-summaries
来查询所有 Foos 的列表,这会在查询网关上触发查询 objects,并且 returns where FooSummary objects,其中FooSummary 是我在侦听 FooCreated 和 FooUpdated 事件的投影中创建的 JPA 实体。
到目前为止所有标准的东西。但是简单的 GET /foos/{id}
呢?
那 URL /foo/{id}
是我想要 return 在位置 header 从 POST /foos
我想要 this GET 到 return all 我的 Foo 的详细信息 - 所有这些都被建模为 FooAggregate 的属性( FooSummary 可能 return 列表的子集)
现在,Axon documentation suggests this:
Standard repositories store the actual state of an Aggregate. Upon each change, the new state will overwrite the old. This makes it possible for the query components of the application to use the same information the command component also uses. This could, depending on the type of application you are creating, be the simplest solution.
但这仅适用于我使用 state-stored 聚合的情况,对吧?我正在使用 Event-Sourced 聚合和 JPA 事件存储。
我的选择似乎是:
忘记 event-sourcing 并使用 stored-state 聚合方法,正如建议的那样 'simplest' 方法(我没有任何特定需要事件源我的聚合 - 虽然我 肯定是 事件源我的投影
在我的 FooSummary 投影 table 中保留完整的详细信息,并使用与
GET /foo-summaries
略有不同的查询将GET /foo/{id}
定向到那里(或者,只需调用它GET /foos
和 return 摘要)创建一个单独的“投影”来存储完整的 Foo 详细信息。这将 实际上与我们在 state-stored 聚合 中使用的相同,因此看起来有点奇怪。
第四个选项 - 这个问题的原因?
回答我自己的问题,但实际上答案来自与 Axon 的 Christian 的讨论。 (在接受我自己的答案之前,将把它打开几天以便获得更好的答案:))
我的选项 #2 和 #3 是正确的答案:差异取决于我的“摘要”预测与“详细”预测的不同程度。如果它们足够接近,选项 #2,如果它们足够不同,则选项 #3。
选项 #1 并不理想,因为即使我们出于其他原因使用状态存储,基于状态存储的查询也会打破 CQRS 中 'S' 的隔离:它使得我们的查询模型依赖于我们的命令模型,当我们的模型变得更复杂时,这可能会导致问题。
(感谢克里斯蒂安)