带有 REST API 的 CQRS

Joh*_*ger 1 rest cqrs node.js event-sourcing

我正在使用 EventSourcing 在 CQRS 上构建 REST 服务,以跨服务分发对我的域的更改。我启动并运行了 REST 服务,有一个用于创建初始模型的 POST 端点,然后是一系列用于更改模型的 PATCH 端点。每个端点都有一个与之关联的命令,客户端将其作为Content-Type参数发送。例如,Content-Type=application/json;domain-command=create-project。我有以下用于在我的任务/项目管理服务上创建项目记录的端点。

  • api.foo.com/project
    • 动词: POST
    • 命令:创建项目
    • 它的作用:在事件存储中插入一个新模型,并设置一些默认值
  • api.foo.com/project/{projectId}
    • 动词:补丁
    • 命令:重命名项目
    • 作用:project-renamed使用新项目名称将事件插入到事件存储中。
  • api.foo.com/project/{projectId}
    • 动词:补丁
    • 命令:重新安排项目
    • 它的作用:将一个project-rescheduled事件插入到事件存储中,并具有新的项目截止日期。
  • api.foo.com/project/{projectId}
    • 动词:补丁
    • 命令: set-project-status
    • 它的作用:将一个project-status-changed事件插入到事件存储中,并具有新的项目状态(活动、计划、存档等)。
  • api.foo.com/project/{projectId}
    • 动词:删除
    • 命令:删除项目
    • 作用:project-deleted事件插入到事件存储中

传统上,在 REST 服务中,您会提供一个 PUT 端点,以便可以替换记录。我不确定它在事件溯源 + CQRS 模式中是如何工作的。我会只使用 POST 和 PATCH 动词吗?

我担心我太细化了,而且每个字段都不需要与之关联的命令。PUT 端点可用于替换片段。不过我担心的是事件存储会不同步,所以我只是坚持使用 PATCH 端点。这种粒度级别是典型的吗?对于一个模型6 个属性我有5 个命令来调整模型的属性。

Mat*_*ist 6

这是我们在帮助开发人员开始使用 CQRS/ES 时经常遇到的一个常见问题。我们需要承认,以纯粹的方式应用 REST 与 DDD/CQRS 非常不匹配,因为命令的意图没有在动词 GET/POST/PUT/PATCH/DELETE 中明确表达(即使你可以content-type像你一样使用做过)。此外,系统的 C/R 端绝对是与 REST 不匹配的 CQRS 系统中的不同资源。

但是,使用 HTTP 为 CQRS/ES 系统提供 API 是非常实用的。

我们通常只POST用于向/commands端点或具有命令名称的端点发送命令,即/commands/create-project。这完全取决于你想变得多么严格。在这种情况下,我们将命令类型嵌入有效负载或作为内容类型。

但是,这完全取决于什么更适合技术堆栈,而您在此处选择的内容通常不会成败解决方案。更重要的部分通常是创建一个好的领域模型,并让整个团队采用这种思维方式。

祝你好运!


Eve*_*ert 5

我想到的一个问题是,REST 到底是 CQRS 的正确范例吗?

一种完全不同的构建方法是不具有以操作为中心的端点,而是将 REST API 构建为一系列事件,您可以向其中添加新事件(使用 POST)。

事件应该是不可变的并且只能追加,所以也许DELETE方法对于突变没有多大意义。

如果你全力使用 CQRS(祝你好运,我听过战争故事),我会倾向于构建一个能够很好地反映该模型的 API。