neos/eventstore

事件源应用程序的存储库

维护者

详细信息

github.com/neos/eventstore

问题

资助包维护!
其他

1.0.1 2024-03-22 15:02 UTC

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