thiagomarini / binocular
在不建造宇宙飞船的情况下进行事件源
1.0.1
2019-07-01 15:55 UTC
Requires
- php: >=7.1.0
Requires (Dev)
- phpunit/phpunit: ~7.0
This package is auto-updated.
Last update: 2024-09-29 05:21:55 UTC
README
在不建造宇宙飞船的情况下进行CQRS + 事件源。一个将事件源从过度工程领域带到现实世界的尝试。
本项目的目标是使您能够在当前堆栈中用PHP进行CQRS + ES,而无需采用任何新技术。有时经典数据库模型不足以表示应用程序的状态。如果您发现自己正在创建数据库视图或使用复杂的SQL查询以不同的方式呈现数据,Binocular就是您所需要的,它将为您的应用程序带来结构和秩序。尽管与事件一起工作需要一些思维方式的转变,您需要考虑事件的产生和消费。但是,您不需要在所有地方或改变应用程序的架构,您只需在数据库模型难以表示状态的地方进行即可。
本项目仅关注ES + CQRS的3个元素
- 事件流:应用程序产生的事件的异步流。写入端。
- 投影:将重放并处理事件流中的事件以计算状态。
- 读取模型:将缓存投影处理事件的结果。读取端。
有关更多信息,请阅读我的支持这一想法的文章:我的帖子。
它有什么不同之处?
- Binocular非常轻量,可以与任何框架一起使用。
- 仅应使用在数据库模型难以表示应用程序状态的地方。
- 投影使用reducer来计算读取模型的状态,有点像 Redux:
previousState + event = newState。Reducers使测试变得极为简单,相同的输入总是产生相同的输出。 - 操作和reducer具有版本号,这样事件就可以无忧地发展。
- 唯一的前提是事件需要持久化到某个地方,以便可以重放。
- 该项目主要由接口和基类组成,您需要自己进行实现并了解放置位置。
为什么以Binocular作为项目名称?
与CQRS一样,双眼视觉发生在两个眼睛的两个单独图像成功结合成大脑中的一个图像时。CQRS有两个眼睛:读取和写入眼睛。
简要说明用法
composer require thiagomarini/binocular
// save some events $eventRepository->store( new UserSignedUp($userId, ['name' => 'John']) ); $eventRepository->store( new UserNameWasUpdated($userId, ['name' => 'John Smith']) ); // use a projection to process the events and calculate the state of its read model $newState = $onboardingProjection->calculateState($userId); // save the read model state $readModelRepository->store($userId, $newState); print_r($newState); // ['name' => 'John Smith']
Laravel示例
如前所述,Binocular可以与任何框架一起使用,您只需知道放置位置。在Laravel的情况下,它已经有一个简单的 观察者实现,这对于与Binocular一起工作已经足够了。
我创建了一个 Laravel示例应用程序。在示例中,我使用User模型作为事件源的根本,这意味着它将有自己的事件表和读取模型表。
概念上需要做的是
- 如果您不想使用PDO,请创建一个 Eloquent存储库实现。
- 为事件和读取模型表创建 迁移。
- 创建一个自定义的
event()全局辅助函数的实现,以便在队列之前保存事件。 - 在 事件监听器中放置一个投影,以计算和保存只读模型的状态。
- 在任何你认为合适的地方触发事件。
- 缓存的状态将在 只读模型 上可用,你可以像在应用程序中使用任何 Eloquent 模型一样使用它。并且记住,只读模型和投影是一对一的关系,这意味着一个投影应该只为一个只读模型生成状态。
在 tests/Examples 文件夹中也有其他纯 PHP 示例。
如何贡献
欢迎 PR :)