当前位置: 首页 > 知识库问答 >
问题:

验证CQRS中与其他域相关的命令

公良理
2023-03-14

我正在学习使用DDD、CQRS和ES开发微服务。这是HTTP RESTful服务。微服务是关于在线商店的。有几个域,如产品、订单、供应商、客户等。域内置在单独的服务中。如果命令有效负载与其他域相关,如何进行验证?

例如,这里是订单服务(命令端)中的addOrderItemCommand负载。

{
"customerId": "CUST111", 
"productId": "SKU222",
"orderId":"SO333"
}

如何验证上面的命令?如何知道客户真的存在于数据库中(查询端客服)并且仍然活跃?如何知道产品存在于数据库中并且产品的状态已发布?如何知道客户是否有资格从相关产品中获得促销价格?

直接调用API(如点对点/ajax/请求promise)来验证此有效负载以便命令端服务可以吗?但我认为,如果API只是为了验证而直接调用,那么性能会变得更差。因为,我们在命令服务之外开发了一个事件处理器,可以从事件中进行侦听,并将事件应用到物质化视图。

非常感谢。

共有2个答案

慕容嘉荣
2023-03-14

与往常一样,一切都取决于域的具体情况,但作为一般原则,跨域验证应该通过读取模型完成。

在这种情况下,我将在每个微服务中维护一个读取模型,以用于验证。当然,这带来了最终一致性的问题。你如何处理这个问题应该取决于你对这个领域的理解。应考虑与更新频率相比的最终一致性长度等因素。与最小化问题的开发成本相比,业务出错的成本。在许多情况下,仅仅记录出现问题的事实就足够了。

我有一篇专门讨论验证的博客文章,您可以在这里找到:如何在CQRS应用程序中验证命令

宣胜
2023-03-14

由于需要查询多个有界上下文才能通过验证,因此需要考虑最终的一致性。这就是说,总有一种可能性,即整个过程可能在“一小”段时间内处于无效状态。例如,可以在接受命令后和订单发货前停用用户。网店是一个复杂的系统,任何子系统都可能出现异常。然而,作为一个事件驱动系统来实现是有帮助的;每次订购过程进入无效状态时,您都可以采取补偿措施/命令。例如,如果用户同时被停用,您可以取消其所有长期订单,释放保留的产品,宣布在愿望列表中有这些产品的潜在客户不可用等等。

DDD中有多种验证,但我遵循的一般规则是,应尽早进行验证,但不影响数据的一致性。因此,为了提前到达,您可以查询readmodel以拒绝不可能有效的命令,并且为了使系统保持一致,您需要在订单发货之前再次进行检查。

现在让我们谈谈你的具体问题:

如何知道客户真的存在于数据库(查询端客服)中并且仍然活跃?

您可以查询readmodel,以验证用户是否存在,以及该用户是否仍处于活动状态。您应该这样做,因为来自无效用户的命令是某种攻击的强烈迹象,您不希望此类命令通过您的系统。然而,即使命令通过了此检查,也不一定意味着订单将被发货,因为在这期间可能会引发其他异常。

如何知道产品存在于数据库中,以及产品的状态已发布?

同样,您可以查询readmodel,以通知用户该产品目前不可用。或者,根据您的业务,如果您知道根据之前的一些统计数据,这些产品将在24小时内可用(例如,您知道电视机每天都会进货),则可以允许该命令通过。或者,您可以让客户选择是否等待。在这种情况下,如果产品在订购(发货)的最后阶段没有库存,您会通知客户产品不再有库存。

如何知道客户是否有资格获得相关产品的促销价格?

您可能需要查询另一个有边界的上下文,如来检查这一点。这取决于促销的验证/使用方式。

为了命令端服务,直接调用API(如点对点/ajax/请求promise)来验证这个有效负载可以吗?但我认为,如果直接调用API只是为了验证,性能会变得更糟。

这取决于您希望系统的弹性以及拒绝无效命令的速度。

同步调用更容易实现,但它们会导致系统弹性较低(您应该注意级联故障并使用断路器等技术来阻止它们)。

异步(即使用事件)调用更难实现,但使您的系统更具弹性。为了进行异步调用,订购系统可以订阅其他系统的事件,并保持一个私有状态,当命令到达时可以查询用于验证目的。这样,即使库存客户管理系统的链接关闭,订购系统也可以继续工作。

无论如何,这真的取决于你的生意,我们谁也不能确切地告诉你该做什么。

 类似资料:
  • 请原谅我在这里缺乏理解,因为我已经进入了三天的冬眠期。 我正在尝试在一个实体上添加验证,这需要将它们与另一个实体进行比较。 例如,以一个人为例。一个人可以有许多身体部位,但最多有两个手臂类型的身体部位(变异除外)。为了验证这一点,在插入新的车身部件时,我需要将其与给定人员的其他车身部件进行比较,并验证该类型的最大值是否已经达到。 我一直在研究Hibernate提供的约束/验证内容,但似乎没有一个涵

  • 综述 有时甚至可能会发生主要的认证机制不包含任何漏洞,但是可能在其他合法的认证用户渠道中存在漏洞。测试应该被实施在识别其他的渠道,以及在测试范围内识别漏洞。 其他用户交互渠道可能被利用绕过主要交互通道,或暴露一些有助于攻击者攻击主要通道的信息。有些渠道可能通过使用不同的主机名或路径来区分自己。例如: 标准网站 为移动或特定设备优化的网站 为无障碍访问优化的网站 其他国家和语言网站 使用相同用户账号

  • 问题内容: 假设我有以下代码 标记为volatile的修改字段及其值不取决于先前的状态。因此,这是正确的多线程代码(不要为实现而烦恼一分钟)。 据我所知,从内存可见性的角度来看,读取volatile变量就像输入锁一样。这是因为正常变量的读取不能与读取易变变量重新排序。 这是否意味着以下代码正确? 问题答案: 是的,从Java 1.5开始,此代码是正确的。 无论有无波动,原子性都不是问题(对对象引用

  • null 我们尝试了几件事: > 发出命令: 激发命令 同步处理此命令,如果命令无效或引发事件,则返回错误。 null 缺点:-据我所知,应该用佐贺来编排流程。这里我们介绍“验证”的概念。我不确定这是不是推荐的方法。 验证是一个非常常见的概念。在分布式完全异步系统中如何处理它?

  • 在一个集合中对业务规则的验证是通过一致性问题的AR进行的。如何验证需要订单集合之外的数据的业务规则? 我也在使用CQRS方法,我认为使用ReadModel来获取验证业务规则所需的数据并不是一个糟糕的选择...您认为呢?

  • 在我的使用阿帕奇·希罗进行AuthC和AuthZ的web应用程序中,我有两个身份验证领域:一个用于常规web接口(称为< code>SsoRealm),另一个用于REST API(称为< code>RestRealm),使用API令牌。由两个领域认证的主体具有分离的权限(和< code > AuthenticationTokens )。如果没有预先存在的会话,并且API调用通过REST接口到达,则