PHP的事件存储、领域仓库和偏好API,附带一个Symfony包

5.0.0-alpha5 2022-02-10 09:58 UTC

README

提供了一套面向领域驱动设计的工具。通过makinacorpus/goat-bundle包提供对Symfony >= 4的自动集成。

状态

这是一种包含许多功能的微框架

  • 命令总线逻辑,包括命令派发器和命令处理器定位器。
  • 使用PostgreSQL的独立消息代理实现。
  • 一个读取消息代理队列并将消息发送到命令总线同步派发器的命令。
  • 一个名称规范化和映射API(例如 \App\Foo\BarApp.Foo.Bar),用于在技术边界之间共享业务标识符。
  • 一些相当通用、稳定且功能性的事件存储实现,带有PostgreSQL驱动程序。
  • 一个事件投影API,用于消费事件存储事件并将它们投影到自定义实现中,用于填充读取模型数据库。
  • 一个经典的仓库模式实现。
  • 偏好API作为伪Symfony环境变量返回。
  • 一个用于将一切联系起来的Symfony包。

总的来说,这代表了一个巨大的功能面,而这个列表中的许多项目并不属于一起。

名称goat本身指代愚蠢或不安全的事物。

该项目已经经历了4个生产项目,仍然存在并得到维护,但不会持续太久。

下一个主要版本,即5.x将是最后一个版本,它代表了当前的状态,其中

  • 偏好API不再存在,并已移动到独立的包makinacorpus/preferences-bundle(你可以在Packagist上查找它)。
  • 仓库模式实现已删除,它在单个项目中实际使用过,并将作为一个独立包进行最小维护(仅修复错误)makinacorpus/goat-domain
  • 名称规范化功能已移动到makinacorpus/normalization包。
  • 新的makinacorpus/message包现在包含共享的消息封装和相关接口。
  • 新的makinacorpus/event-store包现在包含事件存储和投影API。请注意,如果没有任何新用例,项目API本身可能会被弃用。
  • 许多其他死代码片段将被丢弃。
  • 它将主要保持命令总线、派发器、消息代理、事件存储和规范化API。

它将进入仅修复错误的阶段,因为我们仍在使用它的生产项目,但大部分代码将逐步被弃用,以支持新的独立和更准确的包。

  • 现有的makinacorpus/corebus包,它与该包的派发器大致相同,使用更现代的代码,并且经过更广泛的测试,最终将继承此派发器和消息代理代码。

先决条件

由于使用了SQL RETURNING子句,因此它不能与MySQL一起使用。这不是SQL标准功能,但PostgreSQL、SQL Server和Oracle都有这种功能的变体,因此可以使用此包。

目前,只有PostgreSQL是活动的目标,并已进行测试。

功能

  • 使用中间消息中断的领域事件驱动模型,源自DDD和CQS
  • 提供一个事件存储来保存所有内容,并重新播放。

安装

composer req makinacorpus/goat-domain

用法

请记录我。

派发器

分发器(Dispatcher)是一个组件,其行为类似于symfony/messenger组件,它是用户发送和消费消息的接口。

它提供了两种方法

  • 异步消息方法dispatch(),其目的是将消息发送到消息代理,

  • 同步消息方法process(),其目的是消费消息并将它们派发到正确的消息处理器。

基本实现如下

  • dispatch()只是将消息传递给消息代理,
  • process()只是通过处理器定位器获取一个处理器并执行它。

所有其他高级功能,包括事件存储支持,都是通过分发器接口装饰器实现的。

存在一个控制台消费者命令,它简单地从消息代理中获取消息并调用分发器的dispatch()方法。

事件存储

简介

事件存储(EventStore)是一个非常原始的事件源实现,它将应用程序中通过的所有事件保存到一个有序且不可变的追加日志中。

应用程序中执行的所有事件都将保存到这个日志记录机制中。

它的工作方式如下

  • 当一个领域事件通过分发器同步处理后,事件将被直接保存到日志中,包括失败或成功状态(失败事件是指被回滚的事件),

  • 当消息代理消费外部或异步消息时,它会再次通过分发器,并以相同的方式保存。

它的使用是可选的。

一些概念

事件存储允许部分实现基于事件源的系统,或者可以作为纯日志记录机制使用,而不作为实际数据的来源。

在两种情况下,它都将连接到消息总线,并存储系统发生的每条消息或领域事件。为了正常工作,您自己的事件应该实现Goat\Dispatcher\Message\Message接口,以便事件存储能够识别系统中创建或更新的每个聚合或实体,并跟踪对象的生命周期。

您实际上是否识别创建或修改并不重要,只需要一个UUID即可,如果它不存在于索引中,将创建一个新的事件流;如果存在,将向现有流中追加单个事件。

高级配置

请记录我。

Monolog集成

为Monolog提供了一些额外的选项。

有关更多信息,请参阅README.monolog.md文件。

测试

sys/文件夹中存在一个具有各种容器(针对不同PHP版本)的Docker环境。为了使测试在所有PHP版本中都能正常工作,您需要运行composer update --prefer-lowest,否则PHP 7.4的测试将失败。

composer install
composer update --prefer-lowest
cd sys/
./docker-rebuild.sh # Run this only once
./docker-run.sh