nwidart/laravel-broadway

为 Broadway ES/CQRS 包提供的 Laravel 适配器。

2.0.2 2018-11-22 09:04 UTC

This package is auto-updated.

Last update: 2024-09-08 19:17:59 UTC


README

SensioLabsInsight Scrutinizer Code Quality Latest Stable Version Total Downloads Latest Unstable Version License

Laravel Broadway 是 Broadway 包的适配器。

它绑定了 Broadway 所需的所有接口。

为了参考,我已经构建了一个 示例 Laravel 应用程序,它使用了此包和一些事件源技术。

Laravel 5 兼容的包

安装

通过 composer 安装

composer require nwidart/laravel-broadway=~1.0

服务提供者

Laravel 5.5 (自动发现)

如果你使用的是 Laravel 5.5,此包提供自动发现功能,这意味着你可以开始编码——全局服务提供者已经添加。如果你只需要一些服务提供者,请将以下部分添加到你的应用程序的 composer.json 文件中

 "extra": {
    "laravel": {
      "dont-discover": [
        "nWidart/Laravel-broadway"
      ]
    }
  }

Laravel 5.4

要完成安装,您需要添加服务提供者。

这里有两种选择,你可以使用主服务提供者,它将加载以下内容

或者选择仅使用您需要的服务提供者。不知道需要什么?请使用提供的全局服务提供者。

全局服务提供者

   Nwidart\LaravelBroadway\LaravelBroadwayServiceProvider::class

单独的服务提供者

  • 命令总线

    Nwidart\LaravelBroadway\Broadway\CommandServiceProvider::class
  • 事件总线

    Nwidart\LaravelBroadway\Broadway\EventServiceProvider::class
  • 序列化器

    Nwidart\LaravelBroadway\Broadway\SerializersServiceProvider::class
  • 事件存储

    Nwidart\LaravelBroadway\Broadway\EventStorageServiceProvider::class
  • 读取模型

    Nwidart\LaravelBroadway\Broadway\ReadModelServiceProvider::class
  • 元数据丰富器

    Nwidart\LaravelBroadway\Broadway\MetadataEnricherServiceProvider::class
  • 支持

    Nwidart\LaravelBroadway\Broadway\SupportServiceProvider::class

(可选) 发布配置文件和迁移

php artisan vendor:publish

这将发布一个 config/broadway.php 文件和一个 database/migrations/create_event_store_table.php 文件。

(可选) 运行迁移

最后一步,运行上一步发布的迁移来创建事件存储表。

如果你还没有发布供应商文件,可以使用以下命令

php artisan broadway:event-store:migrate table_name

配置

事件存储

要创建事件存储,可以调用以下命令

php artisan broadway:event-store:migrate table_name

在配置文件中,你可以选择使用哪个驱动程序作为事件存储以及使用哪个连接。

'event-store' => [
    'table' => 'event_store',
    'driver' => 'dbal',
    'connection' => 'default',
],

完成之后,你可以在服务提供者中将你的 EventStoreRepositories 绑定如下

$this->app->bind(\Modules\Parts\Repositories\EventStorePartRepository::class, function ($app) {
    $eventStore = $app[\Broadway\EventStore\EventStore::class];
    $eventBus = $app[\Broadway\EventHandling\EventBus::class];
    return new MysqlEventStorePartRepository($eventStore, $eventBus);
});

对于内存中的事件存储,你只需要更改配置文件中的驱动程序,并可能添加一个具有适当名称的新事件存储仓库实现。

读取模型

要在你的应用程序中设置读取模型,你首先需要在包配置中设置所需的读取模型。

完成之后,你可以在服务提供者中将你的 ReadModelRepositories 绑定如下

$this->app->bind(\Modules\Parts\Repositories\ReadModelPartRepository::class, function ($app) {
    $serializer = $app[\Broadway\Serializer\Serializer::class];
    return new ElasticSearchReadModelPartRepository($app['Elasticsearch'], $serializer);
});

以下是一个内存读取模型的示例

$this->app->bind(\Modules\Parts\Repositories\ReadModelPartRepository::class, function ($app) {
    $serializer = $app[\Broadway\Serializer\Serializer::class];
    return new InMemoryReadModelPartRepository($app['Inmemory'], $serializer);
});

请参阅 示例 Laravel 应用程序,特别是 服务提供者,以获取一个工作示例。

注册订阅者

命令处理器

要让 Broadway 知道哪些处理器可用,您需要将名为 broadway.command-subscribers 的键绑定到 Laravel IoC 容器中作为单例。

重要的是要知道 Broadway 的命令处理器类需要注入一个事件存储仓库。

现在只需将命令处理程序数组传递给 laravelbroadway.command.registry 键,或者直接传递一个类,如下所示

$partCommandHandler = new PartCommandHandler($this->app[\Modules\Parts\Repositories\EventStorePartRepository::class]);
$someOtherCommandHandler = new SomeOtherCommandHandler($this->app[\Modules\Things\Repositories\EventStoreSomeRepository::class]);

$this->app['laravelbroadway.command.registry']->subscribe([
    $partCommandHandler,
    $someOtherCommandHandler
]);

// OR

$this->app['laravelbroadway.command.registry']->subscribe($partCommandHandler);
$this->app['laravelbroadway.command.registry']->subscribe($someOtherCommandHandler);

事件订阅者

这基本上与命令处理程序相同,只不过事件订阅者(或监听器)需要一个读取模型仓库。

示例

$partsThatWereManfacturedProjector = new PartsThatWereManufacturedProjector($this->app[\Modules\Parts\Repositories\ReadModelPartRepository::class]);
$someOtherProjector = new SomeOtherProjector($this->app[\Modules\Things\Repositories\ReadModelSomeRepository::class]);

$this->app['laravelbroadway.event.registry']->subscribe([
    $partsThatWereManfacturedProjector,
    $someOtherProjector
]);

// OR

$this->app['laravelbroadway.event.registry']->subscribe($partsThatWereManfacturedProjector);
$this->app['laravelbroadway.event.registry']->subscribe($someOtherProjector);

元数据增强器

Broadways 事件存储表包含一个名为 "metadata" 的字段。在这里,我们可以存储所有应该与特定事件一起保存,但不适合领域(即有效负载)的数据。

例如,您想存储当前登录用户的 ID 或 IP 地址等。

Broadway 使用装饰器来操作事件流。装饰器消耗一个或多个增强器,它们提供实际数据(用户 ID、IP)。在将事件保存到流之前,装饰器将遍历已注册的增强器并应用数据。

以下示例假设您已添加此包的全局服务提供者,或者至少是 Nwidart\LaravelBroadway\Broadway\MetadataEnricherServiceProvider

首先,我们创建增强器。在这个例子中,让我们假设我们对登录用户感兴趣。增强器将添加用户 ID 到元数据并返回修改后的元数据对象。然而,在某些情况下——例如在单元测试中——没有可用的登录用户。为了解决这个问题,可以通过构造函数注入用户 ID。

// CreatorEnricher.php

class CreatorEnricher implements MetadataEnricher
{
    /** @var int $creatorId */
    private $creatorId;


    /**
     * The constructor
     *
     * @param int $creatorId
     */
    public function __construct($creatorId = null)
    {
        $this->creatorId = $creatorId;
    }


    /**
     * @param Metadata $metadata
     * @return Metadata
     */
    public function enrich(Metadata $metadata)
    {
        if ($this->creatorId !== null) {
            $id = $this->creatorId;
        } else {
            $id = Auth::user()->id;
        }

        return $metadata->merge(Metadata::kv('createorId', $id));
    }
}

其次,您需要将增强器注册到装饰器中,并将装饰器传递给您的仓库。

// YourServiceProvider.php

/**
 * Register the Metadata enrichers
 */
private function registerEnrichers()
{
    $enricher = new CreatorEnricher();
    $this->app['laravelbroadway.enricher.registry']->subscribe([$enricher]);
}

$this->app->bind(\Modules\Parts\Repositories\EventStorePartRepository::class, function ($app) {
    $eventStore = $app[\Broadway\EventStore\EventStore::class];
    $eventBus = $app[\Broadway\EventHandling\EventBus::class];
    
    $this->registerEnrichers();
    
    return new MysqlEventStorePartRepository($eventStore, $eventBus, $app[Connection::class], [$app[EventStreamDecorator::class]);
});

要检索元数据,您需要将 DomainMessage 作为第二个参数传递给您的项目中的 apply*-方法。

// PartsThatWhereCreatedProjector.php

public function applyPartWasRenamedEvent(PartWasRenamedEvent $event, DomainMessage $domainMessage)
{
	$metaData = $domainMessage->getMetadata()->serialize();
	$creator = User::find($metaData['creatorId']);    
	
	// Do something with the user
}

其余的都是 Broadway 包的约定。

更新日志

许可协议(MIT)