neos / eventstore
事件源应用程序的存储库
Requires
- php: ^8.1
- ramsey/uuid: ^4.3
- webmozart/assert: ^1.10
Requires (Dev)
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10
- roave/security-advisories: dev-latest
- squizlabs/php_codesniffer: ^4.0.x-dev
This package is auto-updated.
Last update: 2024-09-22 16:04:39 UTC
README
此包提供接口和辅助工具,以使用PHP创建事件源系统
范围
与Neos.EventSourcing不同,此包仅提供底层构建块,依赖项很少,并且没有强烈的意见。
注意
此包主要包含数据传输对象的接口和实现。要实际持久化事件,需要相应的适配器包,例如neos/eventstore-doctrineadapter
用法
通过composer安装
composer require neos/eventstore
附加事件
将单个事件提交到事件存储库
$eventStore->commit( streamName: StreamName::fromString('some-stream'), events: new Event(EventId::create(), EventType::fromString('SomeEventType'), EventData::fromString('{"foo": "bar"}')), expectedVersion: ExpectedVersion::ANY(), );
一次性提交多个事件
$correlationId = Uuid::uuid4()->toString(); $eventStore->commit( streamName: StreamName::fromString('some-stream'), events: Events::fromArray([ new Event(EventId::create(), EventType::fromString('SomeEventType'), EventData::fromString('foo'), correlationId: $correlationId), new Event(EventId::create(), EventType::fromString('SomeOtherType'), EventData::fromString('bar'), correlationId: $correlationId])), ]), expectedVersion: ExpectedVersion::ANY(), );
注意 多个事件只能一次性附加到同一个流
预期版本
事件源系统最终是一致的。这基本上意味着用于基于决策的模型可能已经过时。《ExpectedVersion》可用于确保自模型从事件重建以来,没有向流中附加新事件。该机制可用于实现事件源聚合。
ExpectedVersion::ANY
ExpectedVersion::ANY()
(如上例所示)完全跳过版本检查,仅在不需要严格约束时使用。
ExpectedVersion::NO_STREAM
ExpectedVersion::NO_STREAM()
可以用来确保给定的流尚不存在。这对于表示实体创建的事件很有用。
$eventStore->commit( streamName: StreamName::fromString('customer-' . $customerId->value), events: new Event(EventId::create(), EventType::fromString('CustomerHasSignedUp'), EventData::fromString($customerData->toJson())), expectedVersion: ExpectedVersion::NO_STREAM(), );
如果再次执行相同的代码(使用相同的$customId
),则会失败
ExpectedVersion::STREAM_EXISTS
ExpectedVersion::STREAM_EXISTS()
基本上是NO_STREAM
的相反:如果在流中提交了事件之前失败
读取事件
遍历流中的所有事件
加载所有事件并输出它们的序列号和类型
foreach ($eventStore->load(StreamName::fromString('some-stream')) as $eventEnvelope) { echo $eventEnvelope->sequenceNumber->value . ': ' . $eventEnvelope->event->type->value . PHP_EOL; }
过滤事件流
EventStoreInterface::load()
期望第二个可选参数,允许过滤事件流。这可以用来仅加载特定类型的事件
$stream = $eventStore->load( streamName: StreamName::fromString('some-stream'), filter: EventStreamFilter::create(eventTypes: EventTypes::create(EventType::fromString('SomeEventType'))) );
注意
基于类型过滤事件是一个低级优化,通常不需要,仅在需要时应用。
导航事件流
EventStoreInterface::load()
的结果EventStreamInterface
是流的懒表示。根据实际实现,事件仅在访问时才会加载。
EventStreamInterface
提供四种方法来影响要加载的事件的排序和窗口
withMinimumSequenceNumber()
用于指定应包含在流中的最低SequenceNumber
withMaximumSequenceNumber()
用于指定应包含在流中的最高SequenceNumber
limit()
用于指定要加载的总事件数backwards()
以降序加载事件。
通常,withMinimumSequenceNumber()
用于仅加载尚未由事件处理程序处理的事件,但有时允许任意事件流导航可能很有用。
以下示例将按降序读取序列号在500到1000之间最多10个事件
$stream = $eventStore->load(StreamName::fromString('some-stream')) ->withMinimumSequenceNumber(SequenceNumber::fromInteger(500)) ->withMaximumSequenceNumber(SequenceNumber::fromInteger(1000)) ->limit(10) ->backwards();
删除事件
事件是系统中的唯一真相来源,因此永远不会被删除。从理论上讲。在实践中,能够删除不再使用的流可能会有用。
以下示例将删除"some-stream"中的所有事件
$eventStore->deleteStream(StreamName::fromString('some-stream'));
警告
出于明显的原因,这种方法应谨慎使用。大多数情况下,有更好的方法来解决似乎需要删除事件的问题。另外,注意,某些事件存储实现可能不支持此功能
更多示例
有关更多示例,请参见测试。
贡献
许可
请参阅LICENSE