spatie / laravel-eventsauce
在 Laravel 应用中使用 EventSauce
Requires
- php: ^8.0|^7.4
- ext-json: *
- eventsauce/eventsauce: ^0.8
- illuminate/bus: ^7.0|^8.0
- illuminate/container: ^7.0|^8.0
- illuminate/queue: ^7.0|^8.0
- illuminate/support: ^7.0|^8.0
- ramsey/uuid: ^4.0
- spatie/temporary-directory: ^1.2
Requires (Dev)
- mockery/mockery: ^1.4
- orchestra/testbench: ^5.0|^6.0
- phpunit/phpunit: ^9.4.0
README
在 Laravel 应用中使用 EventSauce
EventSauce 是一种简单的方法,可以将事件溯源引入 PHP 项目。此包允许 EventSauce 利用 Laravel 的迁移、模型和作业。它还可以帮助生成命令和事件的代码。如果您想在 Laravel 应用中使用 EventSauce,这个包就是您的最佳选择!
在使用 laravel-eventsauce 之前,您应该已经熟悉如何使用 EventSauce。
以下是一个如何创建一个新的聚合根和匹配的存储库的快速示例。让我们运行这个命令
php artisan make:aggregate-root "MyDomain\MyAggregateRoot"
App\MyDomain\MyAggregateRoot
和 App\MyDomain\MyAggregateRootRepository
类将被创建。还将向您的应用程序添加一个创建 my_aggregate_root_domain_messages
的迁移。这是 MyAggregateRootRepository
的样子
namespace App\MyDomain; use App\Domain\Account\Projectors\AccountProjector; use App\Domain\Account\Projectors\TransactionCountProjector; use Spatie\LaravelEventSauce\AggregateRootRepository; /** @method \App\MyDomain\MyAggregateRoot retrieve */ class MyAggregateRootRepository extends AggregateRootRepository { /** @var string */ protected $aggregateRoot = MyAggregateRoot::class; /** @var string */ protected $tableName = 'my_aggregate_root_domain_messages'; /** @var array */ protected $consumers = [ ]; /** @var array */ protected $queuedConsumers = [ ]; }
您可以将消费者的类名放在 $consumers
数组中。在 $queuedConsumers
数组中的消费者将通过队列作业调用并传递其消息。
MyAggregateRootRepository
可以在任何类中注入和使用。在这个例子中,我们假设您已经在 MyAggregateRoot
上手动创建了一个 performMySpecialCommand
方法。
namespace App\MyDomain; class CommandHandler { /** @var \EventSauce\EventSourcing\AggregateRootRepository */ private $repository; public function __construct(MyAggregateRootRepository $repository) { $this->repository = $repository; } public function handle(object $command) { $aggregateRootId = $command->identifier(); $aggregateRoot = $this->repository->retrieve($aggregateRootId); try { if ($command instanceof MySpecialCommand) { $aggregateRoot->performMySpecialCommand($command); } } finally { $this->repository->persist($aggregateRoot); } } }
支持我们
我们在创建 最佳开源包 方面投入了大量资源。您可以通过 购买我们的付费产品之一 来支持我们。
我们非常感激您从家乡寄来明信片,并提及您正在使用我们哪个包。您可以在 我们的联系页面 找到我们的地址。我们将所有收到的明信片发布在我们的 虚拟明信片墙 上。
安装
您可以通过 composer 安装此包。
composer require spatie/laravel-eventsauce
接下来,您必须发布 eventsauce
配置文件。
php artisan vendor:publish --provider="Spatie\LaravelEventSauce\EventSauceServiceProvider" --tag="config"
这是将要发布到 config/eventsauce.php
的文件内容
return [ /* * Types, commands and events can be generated starting from a yaml file. * Here you can specify the input and the output of the code generation. * * More info on code generation here: * https://eventsauce.io/docs/getting-started/create-events-and-commands */ 'code_generation' => [ [ 'input_yaml_file' => null, 'output_file' => null, ], ], /* * This connection name will be used to store messages. When * set to null the default connection will be used. */ 'database_connection' => null, /* * This class will be used to store messages. * * You may change this to any class that implements * \EventSauce\EventSourcing\MessageRepository */ 'message_repository' => \Spatie\LaravelEventSauce\MessageRepository::class, /* * This class will be used to put EventSauce messages on the queue. * * You may change this to any class that extends * \Spatie\LaravelEventSauce\QueuedMessageJob::class */ 'queued_message_job' => \Spatie\LaravelEventSauce\QueuedMessageJob::class, ];
使用
生成聚合根和存储库
可以使用此命令生成聚合根和匹配的存储库
php artisan make:aggregate-root "MyDomain\MyAggregateRoot"
此命令将创建 App\MyDomain\MyAggregateRoot
和 App\MyDomain\MyAggregateRootRepository
。
这是 MyAggregateRootRepository
的样子
namespace App\MyDomain; use App\Domain\Account\Projectors\AccountProjector; use App\Domain\Account\Projectors\TransactionCountProjector; use Spatie\LaravelEventSauce\AggregateRootRepository; /** @method \App\MyDomain\MyAggregateRoot retrieve */ class MyAggregateRootRepository extends AggregateRootRepository { /** @var string */ protected $aggregateRoot = MyAggregateRoot::class; /** @var string */ protected $tableName = 'my_aggregate_root_domain_messages'; /** @var array */ protected $consumers = [ ]; /** @var array */ protected $queuedConsumers = [ ]; }
如果您不需要消费者或队列消费者,可以安全地删除这些变量。唯一必需的变量是 $aggregateRoot
。
当然,您也可以手动创建聚合根存储库。只需创建一个类,让它扩展 Spatie\LaravelEventSauce\AggregateRootRepository
。接下来,在一个受保护的 $aggregateRoot
属性中放入您的聚合根的完全限定类名。最后,添加一个包含您要存储领域消息的表名的 $tableName
属性。
配置聚合根存储库
指定聚合根
$aggregateRoot
属性应包含一个聚合根的完全限定类名。一个有效的聚合根是任何实现 EventSauce\EventSourcing\AggregateRoot
的类。
添加消费者
消费者是接收所有事件并对它们执行某些操作的类,例如创建投影。$consumers
属性应是一个包含消费者类名的数组。一个有效的消费者是任何实现 EventSauce\EventSourcing\Consumer
的类。
添加队列消费者
除非您需要在同一请求中与您的命令或事件一起使用消费者结果,否则建议让消费者在队列中执行工作。《$queuedConsumers
》属性应是一个包含消费者类名的数组。任何实现《EventSauce\EventSourcing\Consumer
》的类都是有效的消费者。
如果有任何消息需要发送给这些消费者中的任何一个,默认情况下,包会通过《Spatie\LaravelEventSauce\QueuedMessageJob
》来调度。
自定义传递消息到队列消费者的作业
默认情况下,使用《Spatie\LaravelEventSauce\QueuedMessageJob
》来传递消息给队列消费者。您可以通过在《eventsauce
》配置文件中将《queued_message_job
》条目设置为自定义作业的类来自定义此作业。任何扩展《Spatie\LaravelEventSauce\QueuedMessageJob
》的类都是有效的作业。
更改《queued_message_job
》条目将更改所有聚合根存储库的默认作业。如果您想为特定的存储库更改作业类,请向该存储库添加一个《$queuedMessageJob
》属性。
以下是一个示例
// ... class MyAggregateRootRepository extends AggregateRootRepository { // ... protected $queuedMessageJob = MyCustomJob::class; }
您可以使用该自定义作业添加属性来控制超时、最大尝试次数和要使用的队列。有关如何配置作业的更多信息,请参阅《Laravel关于队列的文档》。
以下是一个自定义作业的示例。
use Spatie\LaravelEventSauce\QueuedMessageJob; class MyCustomJob extends QueuedMessageJob { /* * The name of the connection the job should be sent to. */ public $connection = 'my-custom-connection'; /* * The name of the queue the job should be sent to. */ public $queue = 'my-custom-queue'; /* * The number of times the job may be attempted. * * @var int */ public $tries = 5; /* * The number of seconds the job can run before timing out. * * @var int */ public $timeout = 120; /* * The number of seconds before the job should be made available. * * @var int|null */ public $delay; }
自定义存储消息的表名
您的聚合根存储库上的《$tableName
》属性决定了消息的存储位置。只要您已创建一个具有以下列的具有该名称的表,您就可以将其更改为任何您想要的名称:
Schema::create('custom_table_name', function (Blueprint $table) { $table->increments('id'); $table->string('event_id', 36); $table->string('event_type', 100); $table->string('aggregate_root_id', 36)->nullable()->index(); $table->dateTime('recorded_at', 6)->index(); $table->text('payload'); });
指定连接
Laravel支持多个数据库连接。默认情况下,聚合根将使用Laravel的默认连接。如果您想让所有聚合根使用相同的替代连接,请在《eventsauce
》配置文件的《connection
》属性中指定该连接名称。
如果您想让特定的存储库使用替代连接,只需在《$connection
》属性中指定其名称即可。
// ... class MyAggregateRootRepository extends AggregateRootRepository { // ... protected $connection = 'connection-name'; }
代码生成
我们可以从YAML文件开始生成类型、事件和命令。您可以在《使用Yaml定义命令和事件》部分中阅读有关YAML文件内容以及生成的输出的更多信息。
要生成代码,请在《eventsauce
》配置文件的《code_generation
》部分中填写密钥,并执行此命令。
php artisan eventsauce:generate
测试
composer test
变更日志
请参阅《CHANGELOG》以获取有关最近更改的更多信息。
贡献
请参阅《CONTRIBUTING》以获取详细信息。
安全
如果您发现与安全相关的任何错误,请通过security@spatie.be发送邮件,而不是使用问题跟踪器。
Postcardware
您可以自由使用此包,但如果它进入您的生产环境,我们非常感谢您从您家乡寄给我们一张明信片,说明您正在使用我们的哪些包。
我们的地址是:Spatie,Kruikstraat 22,2018 Antwerp,比利时。
我们将在我们的公司网站上发布所有收到的明信片《在这里》。
鸣谢
此包的初始版本基于《LaravelEventSauce》的开发版本。
许可证
麻省理工学院许可证(MIT)。有关更多信息,请参阅许可证文件。