应该从API返回CQRS命令的内容?

ale*_*bit 13 rest http cqrs

据我所知,在通过RESTful HTTP API公开的面向CQRS的API中,命令和查询通过HTTP谓词表示,命令是异步的并且通常返回202 Accepted,而查询获取您需要的信息.有人问我以下内容:假设他们想要更改某些信息,他们必须发送命令然后查询以获得结果状态,为什么要强制客户端发出两个HTTP请求,只需返回他们想要的内容即可单个HTTP请求中的命令的HTTP响应?

Ale*_*rev 18

几个月前我们在DDD/CRQS邮件列表中进行了长时间的对话(链接).讨论的一部分是"单向命令",这就是我认为你所假设的.你可以发现Greg Young反对这种模式.命令会更改状态,因此容易出现故障,这意味着它可能会失败,您应该支持此操作.具有POST/PUT请求的REST API为此提供了完美的支持,但您不应该只返回202 Accepted,而是真正给出一些有意义的结果.有些人返回200成功,还有一些包含URL的对象来检索新创建或更新的对象.如果命令处理程序失败,则应返回500并显示错误消息.

具有即发即弃命令是危险的,因为它可以给消费者一个关于系统状态的错误想法.


Byr*_*ahl 8

我的团队最近也就这件事进行了激烈的讨论.感谢您发布问题.我通常是"火与忘记"风格命令的捍卫者.我的立场一直是,如果你希望有一天能够转移到异步命令调度程序,那么你就不能允许命令返回任何东西.这样做会减少您的机会,因为异步命令没有太多方法可以将值返回到原始http调用.我的一些队友真的挑战了这个想法,所以我不得不开始思考我的位置是否真的值得捍卫.

然后我意识到异步或非异步只是一个实现细节.这让我意识到,使用我们的框架,我们可以构建中间件来完成异步调度程序正在做的事情.因此,我们可以按照我们想要的方式构建命令处理程序,返回有意义的东西,然后让处理程序框架处理"何时".

示例:我的团队目前正在node.js中构建一个http API.我们将返回新创建的资源的详细信息,而不是要求POST命令仅返回空白202.这有助于前端继续前进.前端POSTS一个小部件,并使用与通道名称相同的命令打开到服务器的Web套接字的通道.请求到达服务器并被中间件拦截,中间件将其传递给服务总线.当命令最终由处理程序同步处理时,它通过Web套接字"返回"并且前端很高兴.可以轻松禁用中间件,使API再次同步.


use*_*727 5

没有什么能阻止你这样做。如果您同步执行命令并同步创建投影,那么在执行命令并返回结果后直接进行查询将很容易。如果您通过 rest-api 异步执行此操作,则您没有查询结果要发回。如果您在系统内异步执行此操作,则可以等待创建投影,然后将响应发送给客户端。

重要的是您以经典的 CQRS 样式将写入和读取模型分开。这并不意味着您不能在执行命令时在同一请求中执行读取操作。当然,您可以向服务器发送命令,然后使用 SignalR(或其他东西)等待您的投影已创建/更新的通知。我没有看到等待在服务器端而不是在客户端创建投影的问题。

您如何执行此操作将影响您的基础架构和错误处理。此外,如果您一次返回结果,您将保持 HTTP 请求打开的时间更长。