nwidart / laravel-broadway
为 Broadway ES/CQRS 包提供的 Laravel 适配器。
Requires
- php: >=5.5.9
- broadway/broadway: ~1.0.0
- broadway/event-store-dbal: ^0.1.2
- doctrine/dbal: ~2.5
- illuminate/support: 5.1.*|5.2.*|5.3.*|5.4.*|5.5.*|5.6.*|5.7.*
Requires (Dev)
- phpunit/phpunit: 4.0
Suggests
- broadway/read-model-elasticsearch: For persisting read models in elasticsearch
This package is auto-updated.
Last update: 2024-09-08 19:17:59 UTC
README
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 包的约定。