node.js - 我应该在 Controller 和域服务之间放置命令总线吗?

标签 node.js design-patterns crud cqrs nestjs

我正在后端工作并尝试实现 CQRS 模式。 我对事件非常清楚,但有时会在命令方面遇到困难。

我已经看到命令是由用户请求的,例如 ChangePasswordCommand。然而,在实现层面,用户只是调用一个由某个 Controller 处理的端点。

我可以将 UserService 注入(inject)我的 Controller ,它将处理领域逻辑,这就是基本教程的做法(我使用 Nest.js)。但是我觉得也许这是我应该使用命令的地方——所以我应该在我的 Controller 中执行命令 ChangePasswordCommand 然后域模块会处理它吗?

重要的是我需要命令的返回值,从实现的角度来看这不是问题,但它在 CQRS 方面看起来不太好 - 我应该同时添加和获取。

或者最后一个选项可能是在 Controller 中执行命令,然后在命令处理程序中发出事件 (PasswordChangedEvent)。接下来,等待事件返回并将值返回到 Controller 中。

最后一个选项对我来说似乎很好,但我在请求生命周期内的清晰实现方面遇到了问题。

我根据 https://docs.nestjs.com/recipes/cqrs

最佳答案

虽然 answer @cperson 在技术上是正确的,我想添加一些细微差别。

首先,答案描述中可能不清楚,它建议“在命令处理程序中发出事件 (PasswordChangedEvent)”。这也是我更喜欢的,但要注意:

  • Command 是基础设施层的一部分,Event 是域的一部分。
  • 因此,您应该从命令中触发发出事件的 AggregateRoot 上的代码。
  • 这可以通过 mergeObjectContexteventBus.publish 完成(参见 NestJS docs )。
  • 可以从其他域对象应用事件,但聚合通常是发射器(在提交时)。

我想说明的另一点是假定事件源架构,即应用 CQRS/ES。虽然 CQRS 通常与事件溯源结合使用,但没有任何规定这样做。事件溯源可以提供额外的优势,但也带来了显着增加的复杂性。您应该仔细权衡拥有 ES 的利弊。

在许多情况下,您不需要事件溯源。只有 CQRS 已经给你带来了很多好处,例如让你的域/限界上下文得到很好的包含。读写分离、单一职责命令 + 查询(通常更 SOLID)、更简洁的架构等。在更高的层次上,更容易将焦点从 “我如何实现它(CRUD-wise)”​​转移? '“这些用户需求如何适应领域模型?”

没有 ES,你可以有一个单一的关系数据库,例如坚持使用 TypeORM。您可以保留事件,但这不是必需的。在许多情况下,您可以避免客户端需要订阅事件的最终一致性(也许您只是使用它们来驱动 saga 并更新读取端 View /投影)。

您始终可以仅从 CQRS 开始,然后在需要时添加事件溯源。

关于node.js - 我应该在 Controller 和域服务之间放置命令总线吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56761837/

相关文章:

java - 两个 JFrame 之间交换 Swing 信息的模式

php - 有没有好的 PHP CRUD 代码生成器?

node.js - 如何使用 passport.js 身份验证从 facebook 获取个人资料数据?

node.js - 基本 db-mysql 设置错误

linux - 生产者-消费者模式不适合我们的应用程序?或者只是使用上的误解?

c# - 存储库和查询对象模式。如何实现复杂查询

javascript - Ajax 结果改变 Jade 赋值变量

angularjs - 使用 Node Buffer 或 fileStream 进行 formData 文件上传

java - Spring Data JPA 到深入而奇怪的映射

php - 对所有 Controller 使用单个 crud 模型,而不是对每个 Controller 使用单独的模型