如何在同一个 php 进程中通过异步命令 (CQRS) 检索新创建的实体?
How to retrieve newly created entity by asynchronous command (CQRS) in same php process?
我正在使用 CQRS 实现 PHP 应用程序。
假设我有 CreateOrderCommand
而当我有
$command = new CreateOrderCommand(/** some data**/);
$this->commandBus->handle($command);
CommandBus 现在只需将命令传递给适当的 CreateOrderCommandHandler
class 就像:
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
仅序列化命令并将其发送到兔子队列的实现。
那么,最终处理命令的进程可能是某个 运行 消费者,这里需要进程之间的某种通信 - 能够以某种方式从消费者那里通知原始用户进程,它已完成(包含一些信息,例如新实体的 ID)。
我知道有 GUID 的解决方案 - 我可以用 GUID 标记命令。但是然后呢:
public function createNewOrder(/** some data**/){
$command = new CreateOrderCommand(/** some data**/);
$this->commandBus->handle($command);
$guid = $command->getGuid();
// SOME IMPLEMENTATION
return $createdOrder;
}
SOME IMPLEMENTATION 应该根据具有特定 GUID 的命令对事件进行一些检查(因此我也需要实现一些事件系统),例如能够回显进度或 OrderCreatedEvent
只是 return 这是我将从该事件中获得的 ID。异步处理命令的消费者进程可能例如将事件提供给兔子,用户客户端将接受它们并做出适当的响应(回显进度,例如 return 新创建的实体)。
但是怎么做呢? GUID 的解决方案是唯一的吗?什么是可接受的解决方案实施?或者,我错过了什么? :)
获取有关创建的 ID 的信息的最简单方法 aggregate/entity 是将其添加到命令中。所以前端生成 id 并将其与数据一起传递。但是要使此解决方案有效,您需要使用 uuid 而不是普通的数据库整数,否则您可能会发现自己在数据库端重复标识符。
如果命令是异步的并执行如此耗时的操作,您肯定可以从消费者发布事件。所以客户端via.e.g。 websockets 实时接收信息。
或者询问后端是否存在命令中的id的订单,时不时地,当资源存在时,将他重定向到正确的页面。
我正在使用 CQRS 实现 PHP 应用程序。
假设我有 CreateOrderCommand
而当我有
$command = new CreateOrderCommand(/** some data**/);
$this->commandBus->handle($command);
CommandBus 现在只需将命令传递给适当的 CreateOrderCommandHandler
class 就像:
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
仅序列化命令并将其发送到兔子队列的实现。
那么,最终处理命令的进程可能是某个 运行 消费者,这里需要进程之间的某种通信 - 能够以某种方式从消费者那里通知原始用户进程,它已完成(包含一些信息,例如新实体的 ID)。
我知道有 GUID 的解决方案 - 我可以用 GUID 标记命令。但是然后呢:
public function createNewOrder(/** some data**/){
$command = new CreateOrderCommand(/** some data**/);
$this->commandBus->handle($command);
$guid = $command->getGuid();
// SOME IMPLEMENTATION
return $createdOrder;
}
SOME IMPLEMENTATION 应该根据具有特定 GUID 的命令对事件进行一些检查(因此我也需要实现一些事件系统),例如能够回显进度或 OrderCreatedEvent
只是 return 这是我将从该事件中获得的 ID。异步处理命令的消费者进程可能例如将事件提供给兔子,用户客户端将接受它们并做出适当的响应(回显进度,例如 return 新创建的实体)。
但是怎么做呢? GUID 的解决方案是唯一的吗?什么是可接受的解决方案实施?或者,我错过了什么? :)
获取有关创建的 ID 的信息的最简单方法 aggregate/entity 是将其添加到命令中。所以前端生成 id 并将其与数据一起传递。但是要使此解决方案有效,您需要使用 uuid 而不是普通的数据库整数,否则您可能会发现自己在数据库端重复标识符。
如果命令是异步的并执行如此耗时的操作,您肯定可以从消费者发布事件。所以客户端via.e.g。 websockets 实时接收信息。
或者询问后端是否存在命令中的id的订单,时不时地,当资源存在时,将他重定向到正确的页面。