CQRS:命令返回值 [英] CQRS: Command Return Values

查看:107
本文介绍了CQRS:命令返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于命令是否应该具有返回值,似乎存在无尽的困惑.我想知道是否只是因为参与者没有说明他们的背景或情况而感到困惑.

There seems to be endless confusion about whether commands should or should not have return values. I would like to know if the confusion is simply because the participants have not stated their context or circumstances.

以下是混乱的例子...

Here are examples of the confusion...

  • Udi Dahan说命令没有将错误返回给客户端".但在同一文章中他显示了一个图,其中命令确实将错误返回给客户.

  • Udi Dahan says commands are "not returning errors to the client," but in the same article he shows a diagram where commands indeed return errors to the client.

Microsoft Press Store的文章指出该命令...不返回响应".但随后给出了模糊的警告:

A Microsoft Press Store article states "the command...doesn't return a response" but then goes on to give an ambiguous caution:

随着战场经验在CQRS上的增长,一些实践得到巩固并趋于成为最佳实践.在某种程度上与我们刚才所说的相反...今天普遍认为,命令处理程序和应用程序都需要知道事务操作的进行方式.结果必须是已知的...

As battlefield experience grows around CQRS, some practices consolidate and tend to become best practices. Partly contrary to what we just stated... it is a common view today to think that both the command handler and the application need to know how the transactional operation went. Results must be known...

  • Jimmy Bogard说"

    • Jimmy Bogard says "commands always have a result" but then makes extra effort to show how commands return void.
    • 那么,命令处理程序是否返回值?

      Well, do command handlers return values or not?

      从吉米·鲍嘉(Jimmy Bogard)的" CQRS神话中获得启示,"我认为这个问题的答案取决于什么程序/上下文的象限".您正在谈论:

      Taking a cue from Jimmy Bogard's "CQRS Myths," I think the answer(s) to this question depends on what programmatic/contextual "quadrant" you are speaking of:

      +-------------+-------------------------+-----------------+
      |             | Real-time, Synchronous  |  Queued, Async  |
      +-------------+-------------------------+-----------------+
      | Acceptance  | Exception/return-value* | <see below>     |
      | Fulfillment | return-value            | n/a             |
      +-------------+-------------------------+-----------------+
      

      接受(例如验证)

      命令接受";主要是指验证.假定必须将验证结果同步地提供给调用方,而不管命令完成"是否生效.是同步的还是排队的.

      Acceptance (e.g. validation)

      Command "Acceptance" mostly refers to validation. Presumably validation results must be given synchronously to the caller, whether or not the command "fulfillment" is synchronous or queued.

      但是,似乎许多从业者并不从命令处理程序中启动验证.从我所看到的,这是因为(1)他们已经找到了一种在应用程序层处理验证的绝佳方法(即,通过数据注释检查有效状态的ASP.NET MVC控制器),或者(2)一种体系结构假设命令已提交到(进程外)总线或队列中.后一种异步形式通常不提供同步验证语义或接口.

      However, it seems many practitioners don't initiate validation from within the command handler. From what I've seen, it is either because (1) they've already found a fantastic way to handle validation at the application layer (i.e. an ASP.NET MVC controller checking valid state via data annotations) or (2) an architecture is in place which assumes commands are submitted to an (out of process) bus or queue. These latter forms of asynchrony generally don't offer synchronous validation semantics or interfaces.

      简而言之,许多设计人员可能希望命令处理程序将验证结果作为(同步)返回值提供,但是他们必须在使用异步工具的限制下生存.

      In short, many designers might want the command handler to provide validation results as a (synchronous) return value, but they must live with the restrictions of they asynchrony tools they are using.

      关于履行";对于命令,发出命令的客户端可能需要知道新创建的记录的scope_identity或故障信息,例如帐户透支".

      Regarding "fulfillment" of a command, the client who issued the command might need to know the scope_identity for a newly created record or perhaps failure information - such as "account overdrawn."

      在实时设置中,似乎返回值最有意义;异常不应用于传达与业务相关的失败结果.但是,在排队"中,上下文...返回值自然毫无意义.

      In a real-time setting it seems that a return value makes the most sense; exceptions should not be used to communicate business-related failure outcomes. However, in a "queuing" context...return values naturally make no sense.

      这可能是所有混乱的总结:

      This is where all the confusion can perhaps be summarized:

      许多(大多数?)CQRS从业者都认为他们现在或将来会合并一个异步框架或平台(总线或队列),因此宣称命令处理程序没有返回值.但是,某些从业人员无意使用此类事件驱动的构造,因此他们会认可(同步)返回值的命令处理程序.

      Many (most?) CQRS practitioners assume they will now, or in the future, incorporate an asynchrony framework or platform (a bus or queue) and thus proclaim that command handlers do not have return values. However, some practitioners have no intention of using such event-driven constructs, and so they will endorse command handlers that (synchronously) return values.

      例如,我相信,当毕竟,他的Mediatr产品是内存工具.考虑到所有这些,我认为Jimmy 仔细地花时间从命令中产生空返回值,并不是因为命令处理程序不应该具有返回值".而是因为他只是希望Mediator类具有一致的接口:

      His Mediatr product is, after all, an in-memory tool. Given all this, I think the reason Jimmy carefully took the time to produce a void return from a command was not because "command handlers should not have return values," but instead because he simply wanted his Mediator class to have a consistent interface:

      public interface IMediator
      {
          TResponse Request<TResponse>(IQuery<TResponse> query);
          TResult Send<TResult>(ICommand<TResult> query);  //This is the signature in question.
      }
      

      ...即使不是所有命令都具有有意义的值要返回.

      ...even though not all commands have a meaningful value to return.

      我正确地捕捉了为什么对这个话题有困惑吗?有什么我想念的吗?

      Am I correctly capturing why there is confusion on this topic? Is there something I'm missing?

      借助给出的答案,我认为我已经消除了混乱.简而言之,如果CQRS命令能够返回指示完成状态的成功/失败,则返回值是有意义的.这包括返回新的数据库行标识,或返回任何不读取或返回域模型(业务)内容的结果.

      With the help of the answers given, I think I've untangled the confusion. Put simply, if a CQRS command is capable of returning a success/failure indicating completion status, then a return value makes sense. This includes returning a new DB row identity, or any result that does not read or return domain model (business) content.

      我认为"CQRS命令"在哪里?出现了混乱,超过了异步"的定义和作用. 基于任务的"任务与基于任务的任务"之间有很大的不同.异步IO和异步架构(例如,基于队列的中间件).在前一种情况下,异步任务"被称为任务".可以并且将提供async命令的完成结果.但是,发送到RabbitMQ的命令将不会类似地接收到请求/响应完成通知.正是异步架构的后一种上下文导致一些人说没有诸如异步命令之类的东西".或命令不返回值".

      I think where "CQRS command" confusion emerges, is over the definition and role of "asynchrony". There is a big difference between "task based" async IO, and an asynchronous architecture (e.g. queue based middle-ware). In the former, the async "task" can and will provide the completion result for the async command. However, a command sent to RabbitMQ will not similarly receive a request/reponse completion notification. It is this latter context of async-architecture that causes some to say "there is no such thing as an async command" or "commands do not return values."

      推荐答案

      遵循 Vladik Khononov的CQRS处理复杂性建议命令处理可以返回与其结果有关的信息.

      Following the advice in Tackling Complexity in CQRS by Vladik Khononov suggests command handling can return information relating to its outcome.

      在不违反任何[CQRS]原则的情况下,命令可以安全地返回以下数据:

      Without violating any [CQRS] principles, a command can safely return the following data:

      • 执行结果:成功或失败;
      • 错误消息或验证错误,以防万一;
      • 如果成功,聚合的新版本号;

      此信息将极大地改善系统的用户体验,因为:

      This information will dramatically improve the user experience of your system, because:

      • 您无需轮询外部源即可获得命令执行结果,而立即获得它.验证命令并返回错误消息变得很简单.
      • 如果要刷新显示的数据,可以使用聚合的新版本来确定视图模型是否反映了已执行的命令.不再显示过时的数据.

      丹尼尔·惠特克(Daniel Whittaker)主张退还一个"

      Daniel Whittaker advocates returning a "common result" object from a command handler containing this information.

      这篇关于CQRS:命令返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆