Laravel 事件投影发布
发布日期 作者 Paul Redmond
Freek Van der Herten 和 Spatie 团队一直在开发 Laravel 事件投影,这是一个用于 Laravel 中事件溯源的包。第一个稳定版本 (v1.0.0) 现已发布!
您可以在您的项目中使用 composer 安装事件投影,并且由于 Laravel 的包自动发现,您在发布包的迁移和配置后即可开始使用!
composer require spatie/laravel-event-projector:^1.0.0
事件投影需要 PHP 7.2,因此您的应用程序需要支持最新版本的 PHP,而不是 Laravel 对 PHP >=7.1.3
的限制。
什么是事件溯源
根据 事件溯源模式,事件溯源的概述如下
不要只存储域中数据的当前状态,而是使用只追加存储来记录对该数据采取的所有操作的完整系列。存储充当系统记录,可用于具体化域对象。通过避免同步数据模型和业务域,这可以简化复杂域中的任务,同时提高性能、可扩展性和响应能力。它还可以为事务数据提供一致性,并维护完整的审计跟踪和历史记录,这些跟踪和历史记录可以启用补偿操作。
我建议您通读整篇文章,它提供了出色的概述以及有关何时使用此模式是合适的以及其他情况下此模式可能无用的想法。
我喜欢 Spatie 从 文档的介绍 中对事件溯源的解释
事件溯源对数据的作用就像 Git 对代码的作用一样。大多数应用程序只将它们当前的状态存储在数据库中。许多有用的信息会丢失:您不知道应用程序是如何到达当前状态的。
事件溯源试图通过存储应用程序中发生的所有事件来解决此问题。您的应用程序状态是通过监听这些事件构建的。
以下是一个传统的例子,可以让您更清楚地了解它。假设您是一家银行。您的客户有账户。存储账户余额是不够的,所有交易也应该被记住。使用事件溯源,余额不是一个独立的数据库字段,而是从存储的交易中计算得出的值。这只是事件溯源带来的众多优势之一。
该包旨在成为在 Laravel 中开始使用事件溯源的简单而务实的途径。
事件投影似乎有助于使事件溯源变得简单,而且文档帮助我巩固了如何使用我已经熟悉的 Laravel 概念来使用事件溯源。
Laravel 中的基本事件溯源
要熟悉使用事件投影包进行事件溯源,您应该查看 编写您的第一个投影,以了解涉及的各个部分。
总的来说(如果您对我的评估不完美,请原谅我,事件溯源对我来说是一个新概念),使用事件投影进行事件溯源涉及
- Eloquent 模型
- 实现
ShouldBeStored
接口的事件 - 投影类
从文档中,以下是一个使用 createWithAttributes
静态方法的模型类示例
namespace App; use App\Events\AccountCreated;use App\Events\AccountDeleted;use App\Events\MoneyAdded;use App\Events\MoneySubtracted;use Illuminate\Database\Eloquent\Model;use Ramsey\Uuid\Uuid; class Account extends Model{ protected $guarded = []; protected $casts = [ 'broke_mail_send' => 'bool', ]; public static function createWithAttributes(array $attributes): Account { /* * Let's generate a uuid. */ $attributes['uuid'] = (string) Uuid::uuid4(); /* * The account will be created inside this event using the generated uuid. */ event(new AccountCreated($attributes)); /* * The uuid will be used the retrieve the created account. */ return static::uuid($attributes['uuid']); } public function addMoney(int $amount) { event(new MoneyAdded($this->uuid, $amount)); } public function subtractMoney(int $amount) { event(new MoneySubtracted($this->uuid, $amount)); } public function delete() { event(new AccountDeleted($this->uuid)); } /* * A helper method to quickly retrieve an account by uuid. */ public static function uuid(string $uuid): ?Account { return static::where('uuid', $uuid)->first(); }}
这里需要注意的是为 AccountCreated
、MoneyAdded
、MoneySubtracted
和 AccountDeleted
触发的事件。
以下是一个 MoneyAdded
事件的示例。ShouldBeStored
接口表示此事件应该存储到事件投影包中
namespace App\Events; use Spatie\EventProjector\ShouldBeStored; class MoneyAdded implements ShouldBeStored{ /** @var string */ public $accountUuid; /** @var int */ public $amount; public function __construct(string $accountUuid, int $amount) { $this->accountUuid = $accountUuid; $this->amount = $amount; }}
最后,以下是一个投影类中事件处理程序的部分示例,用于将钱添加到账户余额(这是我最喜欢的银行事件类型)
public function onMoneyAdded(MoneyAdded $event){ $account = Account::uuid($event->accountUuid); $account->balance += $event->amount; $account->save();}
为了将所有内容联系在一起,以下是一个文档中创建新账户并添加资金的示例
Account::createWithAttributes(['name' => 'Luke']);Account::createWithAttributes(['name' => 'Leia']); $account = Account::where(['name' => 'Luke'])->first();$anotherAccount = Account::where(['name' => 'Leia'])->first(); $account->addMoney(1000);$anotherAccount->addMoney(500);$account->subtractMoney(50);
我想象卢克和莱娅的余额代表着银河系信用标准,尽管我不确定他们是否会像这样出现在网格上。
文档中有一部分让我印象深刻,它体现了使用此包进行事件溯源的优势
投影的妙处在于,您可以在事件发生后编写它们。假设银行里的人想获得每个账户的平均余额报告。您可以编写一个新的投影,重放所有事件,并获得该数据。
事件发生后可以编写新的投影的想法似乎很强大。这意味着您不必一开始就“把所有事情都做好”,而是可以进行迭代。
如果您担心性能,文档声称投影是“非常快地查询”。
了解更多
我鼓励您通读 事件投影文档 以开始使用,并确保您拥有 PHP 7.2 的最新副本。Spatie 还提供了一个 演示 Laravel 事件投影应用程序,展示了您可能想要查看的事件投影包。
您可以在 GitHub 代码库 上下载代码、点赞代码库并为事件投影做出贡献。在撰写本文时,事件投影已经拥有 15 位贡献者,推动了稳定版 1.0 的发布。Spatie 做得好!事件投影看起来像是 Laravel 社区另一个出色的包。