Laravel 事件投影发布

发布日期 作者

Laravel Event Projector Released image

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();
}
}

这里需要注意的是为 AccountCreatedMoneyAddedMoneySubtractedAccountDeleted 触发的事件。

以下是一个 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 社区另一个出色的包。

Paul Redmond photo

Laravel 新闻的特约撰稿人。全栈 Web 开发人员和作者。

归档于
Cube

Laravel 新闻通讯

加入 40,000 多名其他开发者,绝不错过新的技巧、教程等。

Laravel Forge logo

Laravel Forge

轻松创建和管理您的服务器,并在几秒钟内部署您的 Laravel 应用程序。

Laravel Forge
Tinkerwell logo

Tinkerwell

Laravel 开发人员必备的代码运行器。使用 AI、自动完成和对本地和生产环境的即时反馈进行 Tinker 操作。

Tinkerwell
No Compromises logo

不妥协

Joel 和 Aaron,来自不妥协播客的两名经验丰富的开发者,现在可供雇用,为您的 Laravel 项目提供帮助。⬧ 固定费用为 7,500 美元/月。⬧ 没有冗长的销售流程。⬧ 没有合同。⬧ 100% 退款保证。

不妥协
Kirschbaum logo

Kirschbaum

提供创新和稳定性,确保您的 Web 应用程序取得成功。

Kirschbaum
Shift logo

Shift

正在运行旧版本的 Laravel?即时、自动化的 Laravel 升级和代码现代化,使您的应用程序保持新鲜感。

Shift
Bacancy logo

Bacancy

每月只需 2,500 美元,即可为您的项目配备一名经验丰富的 Laravel 开发人员,拥有 4-6 年的经验。获得 160 小时的专用专业知识和 15 天无风险试用。立即安排通话!

Bacancy
Lucky Media logo

Lucky Media

立即获得幸运 - Laravel 开发的理想选择,拥有十多年的经验!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel 电子商务

Laravel 的电子商务。一个开源包,将现代无头电子商务功能的强大功能带入 Laravel。

Lunar: Laravel 电子商务
LaraJobs logo

LaraJobs

官方 Laravel 工作板

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS 启动工具包

SaaSykit 是一款 Laravel SaaS 启动工具包,它包含运行现代 SaaS 所需的所有功能。支付、精美结账、管理面板、用户仪表板、身份验证、就绪组件、统计信息、博客、文档等。

SaaSykit: Laravel SaaS 启动工具包
Rector logo

Rector

您无缝升级 Laravel 的合作伙伴,降低成本,加速创新,助力企业取得成功

Rector
MongoDB logo

MongoDB

通过强大的 MongoDB 和 Laravel 集成增强您的 PHP 应用程序,使开发人员能够轻松高效地构建应用程序。在使用熟悉的 Eloquent API 的同时,支持事务、搜索、分析和移动用例。了解灵活、现代的 MongoDB 数据库如何改变您的 Laravel 应用程序。

MongoDB
Maska is a Simple Zero-dependency Input Mask Library image

Maska 是一个简单、零依赖的输入掩码库

阅读文章
Add Swagger UI to Your Laravel Application image

在您的 Laravel 应用程序中添加 Swagger UI

阅读文章
Assert the Exact JSON Structure of a Response in Laravel 11.19 image

在 Laravel 11.19 中断言响应的精确 JSON 结构

阅读文章
Build SSH Apps with PHP and Laravel Prompts image

使用 PHP 和 Laravel Prompts 构建 SSH 应用程序

阅读文章
Building fast, fuzzy site search with Laravel and Typesense image

使用 Laravel 和 Typesense 构建快速、模糊的网站搜索

阅读文章
Add Comments to your Laravel Application with the Commenter Package image

使用 Commenter 包为您的 Laravel 应用程序添加评论

阅读文章