gpt4 book ai didi

axon - 验证联系人在 Axon 中有唯一的电子邮件

转载 作者:行者123 更新时间:2023-12-04 09:34:54 28 4
gpt4 key购买 nike

我很想知道在使用 Axon 框架来验证电子邮件字段对于联系人聚合的一组电子邮件是唯一的时,最佳实践方法是什么。
示例设置

ContactCreateCommand {
identifier = '123'
name = 'ABC'
email = 'info@abc.com'
}

ContactAggregate {
ContactAggregate(ContactCreateCommand cmd) {
//1. cannot validate email
AggregateLifecycle.apply(
new ContactCreatedEvent(//fields ... );
);
}
}
根据我对如何实现这一点的理解,我已经确定了许多可能的方法来处理这个问题,但也许还有更多。
1. 在聚合中什么都不做
这种方法要求(命令的)调用者在发送命令之前执行查询以通过电子邮件查找联系人,从而在最终一致性允许重复的地方留出几毫秒。
缺点:
  • 然后将要求命令的任何“调用者”执行此验证检查,因为无法使用 Axon 查询处理程序在聚合内执行此检查。
  • 可能会发生重复,因此基于这些事件的所有预测都需要以某种方式处理此重复

  • 2. 在单独的持久层中验证
    这种方法引入了一个新的持久层,可以验证聚合内部的唯一性。
    里面 联系聚合 的命令处理程序联系CreateCommand 然后我们可以针对这个持久层发出一个查询(例如,postgres 中的一个表,上面有一个唯一的索引),我们可以针对这个包含所有集合的数据库验证电子邮件
    缺点:
  • 引入外部持久层(微服务外部)以保证联系人之间的唯一性
  • 应该在持久层中考虑扩展,使用高度扩展的聚合来达到这一点可能会成为瓶颈

  • 3. 使用 Saga 和 Singleton 聚合
    这种方法通过引入最多只能有 1 个实例的聚合来增强以前的设置(例如,目标标识符始终相同)。通过这种方式,我们创建了一个“单例聚合”,它只负责封装所有联系人电子邮件地址的集合。
    ContactEmailValidateCommand {
    identifier = 'SINGLETON_ID_1'
    email='info@abc.com'
    customerIdentifier = '123'
    }
    UniqueContactEmailAggregate {
    @AggregateIdentifier
    private String identifier;

    Set<String> email = new HashSet<>();

    on(ContactEmailValidateCommand cmd) {
    if (email.contains(cmd.email) == false) {
    AggregateLifecycle.apply(
    new ContactEmailInvalidatedEvent(//fields ... );
    } else {
    AggregateLifecycle.apply(
    new ContactEmailValidatedEvent(//fields ... );
    );
    }
    }

    }
    在我们完成这个检查之后,我们可以对 进行适当的重新操作。 ContactEmailInvalidatedEvent 联系EmailValidatedEvent 这可能会使之后的联系无效。
    这种方法的好处是它保持聚合本地的持久性,这可以提供更好的扩展性(随着更多节点的添加,存在更多具有本地管理集的聚合)。
    缺点
  • 相当多的样板替换“创建唯一索引”
  • 这种方法允许“无效”联系人永远污染事件存储
  • 'Singleton Aggregate' 很复杂,以确保它是真实的(也许有更简单或更好的方法)
  • CreateContactCommand 的“调用者”必须检查以查看 Saga
  • 的结果

    其他人如何解决这个问题?我觉得选项 2 可能是最简单的方法,但还有其他选择吗?

    最佳答案

    您实际上在寻找的是基于集合的验证(我认为 here 博客很好地解释了这个概念,以及如何在 Axon 中处理它)。简而言之,验证某个字段是否包含在一组数据中。在进行 CQRS 时,这成为一个有点有趣的推理概念,有几种解决方案(正如您已经描述的那样)。
    我认为最好的解决方案总结在您的第二个选项下,即为电子邮件地址使用专用的持久层。您只需创建一个仅包含电子邮件地址的非常简洁的模型,您将在发出 ContactCreateCommand 之前对其进行验证。 .请注意,此持久层属于命令模型,因为它用于执行业务验证。因此,您将介绍一个示例,在该示例中,您的命令模型中不仅有聚合,还有 View 。正如您正确指出的那样,这个 View 当然需要针对它的用例进行优化。也许引入在应用程序启动时创建的缓存也不错。
    为确保此电子邮件地址 View 尽可能是最新的,最明智的做法是确保它在与 ContactCreatedEvent 相同的事务中更新。 (我假设其中包含一个新的电子邮件地址)已发布。您可以通过为您的“电子邮件地址 View ”提供一个专用的事件处理组件来做到这一点,该组件通过 SubscribingEventProcessor 更新。 (SEP)。这将起作用,因为 SEP 由发布事件的同一线程(您的聚合)调用。
    在发送命令之前查询此模型时,您有几个选项。您可以使用 MessageDispatchInterceptor仅对 ContactCreateCommand 起 react 例如。或者,您介绍一个 Handler Enhancer专门用于 react ContactCreateCommand执行此验证。或者,您引入另一个命令,例如 RequestContactCreationCommand这是针对常规组件的。该组件将处理命令,验证模型,如果获得批准,则发送 ContactCreateCommand .
    这是我对这种情况的两分钱,希望这有助于@vcetinick!

    关于axon - 验证联系人在 Axon 中有唯一的电子邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62634361/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com