如何在同一个php进程中通过异步命令(CQRS)检索新创建的实体?

问题描述:

我正在用CQRS实现PHP应用程序。如何在同一个php进程中通过异步命令(CQRS)检索新创建的实体?

比方说,我有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); 
    } 
} 

一切OK。

但处理是无效的方法,所以我不知道任何进展或结果。我能做些什么,例如火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实现,它只是序列化命令,并将其发送给兔子队列。

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

我知道有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?解决方案的可接受实现是什么?或者,我错过了什么? :)

+1

CQRS最适合DDD和事件采购。你尝试过那些吗? –

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

+0

我以某种方式不喜欢这个想法,那个做某事并需要使用命令创建新实体的服务(只是顺便说一下),应该照顾生成该实体的id。正如我在我的例子中所展示的,我宁愿每一个命令都是用它的GUID创建的,然后我可以从它得到它。然后我有命令的身份证,我知道该听什么。但是,在我的例子中,如何_exactly_可以被监听?它应该是阻塞的,所以没有主动询问存在。 – Tom

+0

Websocket听起来不错,我找到了React PHP http:// reactphp。组织/,但我仍然没有得到如何申请我的例子。当我在谷歌上搜索时,这种情况很少。这将需要一些时间。如果有人能够在答案中详细说明,会没事的。 :) – Tom

+0

你为什么认为该服务应该负责生成ID?无论如何,您都会将其公开给用户,这不是用户不应该意识到的隐藏值。 – Dariss