【问题标题】:CQRS commands and GraphQL mutationsCQRS 命令和 GraphQL 突变
【发布时间】:2020-11-09 21:57:12
【问题描述】:

我刚刚了解了 CQRS,我想将它与基于 GraphQL 的 API 结合到一个项目中。然而,为了做到这一点,我想到了一个问题:根据 CQRS,命令在执行后必须不返回任何内容。但是,根据 GraphQL 约定,突变必须返回实体的更新状态。

我应该如何处理? CQRS 和 GraphQL 不兼容吗?我想到的唯一解决方案是,为了解决突变,首先执行命令,然后执行查询,以获得响应对象。还有什么比这更好的吗?对我来说它看起来不是很有效......

提前致谢

【问题讨论】:

    标签: graphql cqrs


    【解决方案1】:

    我应该如何处理?

    真正的答案?忽略“必须不返回任何东西”的约束;该约束背后的基本假设不成立,因此您不应该过分依赖它。

    具体怎么做取决于你的设计。

    例如,如果您在处理 HTTP 请求的同一进程中更新域模型,那么 (a) 保存域模型,(b) 运行视图投影 是完全合理的事情您刚刚保存的模型的副本,(c) 然后返回视图。

    换句话说,信息经过与“通常”完全相同的转换,除了我们同步执行这些转换,而不是异步执行这些转换。

    如果模型在不同的过程中更新,那么事情会变得更加棘手,因为需要更多的消息传递,并且您可能需要处理超时。例如,您可以想象一个解决方案,您发送命令,然后轮询“读取端”,直到该模型更新以反映您的更改。

    这都是权衡,而这些权衡是选择分布式架构的必然结果。我们选择 CQRS 不是因为它让一切变得更好,我们选择 CQRS 是因为它让一些事情变得更好,另一些事情变得更糟,而且我们所处的环境中,它让事情变得更好比事情变得更糟。

    【讨论】:

    • 加几美分,您可以将 Mutation 返回视为来自 CQRS 的查询。
    • @RodrigoBoratto 你的意思是在突变后使用读取模型进行额外查询吗?
    • 取决于您如何进行查询(和用例),是的。如果你有一个缓存层,可能突变已经改变了它,在返回之前你可能需要一些实体到模式的映射。我通常做的只是返回“模式 ID”,让 GraphQL 处理其余的,主要是因为我使用联合模式,而某些“属性”只存在于其他服务上。
    • schema_id 是否与 entity_id 相同? let the GraphQL handle the rest 你的意思是客户端重取吗?
    【解决方案2】:

    我正在考虑类似的情况,即主要使用 GraphQL 与基于 CQRS 的系统的读取端进行交互。

    然而,在写入方面,我正在考虑使用一个 Web 或 REST API,它有一个接受命令的端点。

    请记住,在 CQRS 中,您不会直接改变实体,而是提交一个命令来表明您的意图/想要做某事。

    或者,在这里大声思考,可以使用 GraphQL 中的突变来创建命令并使用订阅跟踪它们的状态。

    【讨论】:

    • 我明白你的意思,但我不完全喜欢为查询和命令设置单独的端点的想法......你有没有想过打破 GraphQL 关于返回更新实体的“规则”作为结果的突变,而不是只返回一个自定义类型,比如“提交的命令”?
    • 是的,都可以用 GraphQL 完成,但是(正如我的帖子所建议的)我可能只使用一种 GraphQL 命令类型,提交命令并以接受或拒绝(通过命令处理程序)状态返回命令更新和命令标识符,以供将来查询或订阅有关命令状态。
    • 我还想讨论一下,突变返回的内容取决于您。根据 GraphQL,它也可能什么都没有并且没问题。您只需要从客户端重新查询数据,而不是获取更新的响应对象,以使客户端的本地缓存正确。
    猜你喜欢
    • 2021-05-11
    • 2018-09-30
    • 2017-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-31
    • 2019-11-27
    相关资源
    最近更新 更多