2

我正在使用 CQRS 实现 PHP 应用程序。

假设我有CreateOrderCommand,当我有

$command = new CreateOrderCommand(/** some data**/);
$this->commandBus->handle($command);

CommandBus 现在只需将命令传递给适当的CreateOrderCommandHandler类,如下所示:

abstract class SimpleCommandBus implements CommandBus
{
    /** @var ICommandHandlerLocator */
    protected $locator;

    /**
     * Executes command
     *
     * @param Command $command
     */
    public function handle(Command $command)
    {
        $handler = $this->locator->getCommandHandler($command);
        $handler->handle($command);
    }
}

一切还好。

但是处理是无效的方法,所以我对进度或结果一无所知。例如,我可以做些什么来触发CreateOrderCommand,然后在同一进程中获取新创建的实体 ID(可能有一些被动等待它的创建)?

public function createNewOrder(/** some data**/){
  $command = new CreateOrderCommand(/** some data**/);
  $this->commandBus->handle($command);
  // something that will wait until command is done
  $createdOrder = // some magic that retrieves some adress to result data
  return $createdOrder;
}

为了更接近 CQRS 可以提供的功能,命令总线应该能够RabbitMqCommandBus实现只序列化命令并将其发送到兔子队列。

因此,最终处理命令的进程可能是某个正在运行的消费者,并且这里需要进程之间的某种通信 - 以便能够以某种方式从消费者那里通知原始用户进程,它已完成(带有一些信息,例如新实体)。

我知道有 GUID 的解决方案 - 我可以用 GUID 标记命令。但是然后呢:

public function createNewOrder(/** some data**/){
  $command = new CreateOrderCommand(/** some data**/);
  $this->commandBus->handle($command);
  $guid = $command->getGuid();
  // SOME IMPLEMENTATION
  return $createdOrder;
}

某些实现应该对具有特定 GUID 的命令进行一些事件检查(因此我也需要实现一些事件系统),以便能够例如回显进度或OrderCreatedEvent仅返回我将从该事件中获得的 ID。例如,异步处理命令的消费者进程可能会向兔子提供事件,用户客户端会接受它们并做出适当的响应(例如,回显进度,返回新创建的实体)。

但是怎么做呢?GUID 的解决方案是唯一的吗?什么是可接受的解决方案实现?或者,我错过了什么?:)

4

1 回答 1

1

获取有关已创建聚合/实体的 id 信息的最简单解决方案是将其添加到命令中。所以前端会生成 id 并将其与数据一起传递。但是要使此解决方案有效,您需要使用 uuid 而不是普通的数据库整数,否则您可能会发现自己在数据库端复制了标识符。
如果命令是异步的并且执行如此耗时的操作,您肯定可以从消费者那里发布事件。所以客户端通过.eg websockets 实时接收信息。或者用命令中的id询问后端订单是否存在,不时以及当资源存在时,将他重定向到正确的页面。

于 2017-02-19T10:35:08.230 回答