Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Event Sourcing Laravel Package

prooph/event-sourcing

Lightweight PHP event sourcing library with out-of-the-box integration for prooph/event-store. Provides an AggregateRoot base and AggregateTranslator, plus UUID generation and assertions support. Note: project was supported until Dec 31, 2019 and is deprecated.

View on GitHub
Deep Wiki
Context7

Interop Factories

Instead of providing a module, a bundle, a bridge or similar framework integration prooph/event-store ships with interop factories.

Factory-Driven Creation

The concept behind these factories (see src/Container folder) is simple but powerful. It allows us to provide you with bootstrapping logic for the event store and related components without the need to rely on a specific framework. However, the factories have three requirements.

Requirements

  1. Your Inversion of Control container must implement the PSR Container interface.
  2. interop-config must be installed
  3. The application configuration should be registered with the service id config in the container.

Note: Don't worry, if your environment doesn't provide these requirements, you can always bootstrap the components by hand. Just look at the factories for inspiration in this case.

AggregateRepositoryFactory

To ease set up of repositories for your aggregate roots prooph/event-store also ships with a Prooph\EventStore\Container\Aggregate\AbstractAggregateRepositoryFactory. It is an abstract class implementing the container-interop RequiresContainerId interface. The containerId method itself is not implemented in the abstract class. You have to extend it and provide the container id because each aggregate repository needs a slightly different configuration and therefore needs its own config key.

Note: You can have a look at the ProophTest\EventStore\Mock\RepositoryMockFactory. It sounds more complex than it is.

Let's say we have a repository factory for a User aggregate root. We use user_repository as container id and add this configuration to our application configuration:

[
    'prooph' => [
        'event_sourcing' => [
            'aggregate_repository' => [
                'user_repository' => [ //<-- here the container id is referenced
                    'repository_class' => MyUserRepository::class, //<-- FQCN of the repository responsible for the aggregate root
                    'aggregate_type' => MyUser::class, //<-- The aggregate root FQCN the repository is responsible for
                    'aggregate_translator' => 'user_translator', //<-- The aggregate translator must be available as service in the container
                ],
            ],
        ],
    ],
]

If you want to speed up loading of aggregates with a snapshot store then you need to make it available as service in the container and use the configuration to let the factory inject the snapshot store in the repository.

Also you need to install Prooph SnapshotStore and a persistable implementation of it, like pdo-snapshot-store or mongodb-snapshot-store.

[
    'prooph' => [
        'event_sourcing' => [
            'aggregate_repository' => [
                'user_repository' => [
                    'repository_class' => MyUserRepository::class,
                    'aggregate_type' => MyUser::class,
                    'aggregate_translator' => 'user_translator',
                    'snapshot_store' => 'awesome_snapshot_store' // <-- SnapshotStore service id
                ],
            ],
        ],
    ],
    // zf3 service manager example to configure snapshot store service below
    'dependencies' => [
        'aliases' => [
            'awesome_snapshot_store' => InMemorySnaphotStore::class,
        ],
        'factories' => [
            InMemorySnaphotStore::class => InvokableFactory::class,
        ],
    ],
]

You can also configure a custom stream name (default is event_stream):

[
    'prooph' => [
        'event_sourcing' => [
            'aggregate_repository' => [
                'user_repository' => [
                    'repository_class' => MyUserRepository::class,
                    'aggregate_type' => MyUser::class,
                    'aggregate_translator' => 'user_translator',
                    'snapshot_store' => 'awesome_snapshot_store', // <-- SnapshotStore service id
                    'stream_name' => 'user_stream' // <-- Custom stream name
                ],
            ],
        ],
    ],
]

You can add your custom event store too (default is EventStore::class):

[
    'prooph' => [
        'event_sourcing' => [
            'aggregate_repository' => [
                'user_repository' => [
                    'repository_class' => MyUserRepository::class,
                    'event_store' => MyCustomEventStore::class, // <-- Custom event store service id
                    'aggregate_type' => MyUser::class,
                    'aggregate_translator' => 'user_translator',
                ],
            ],
        ],
    ],
]

You can also disable the identity map

[
    'prooph' => [
        'event_sourcing' => [
            'aggregate_repository' => [
                'user_repository' => [
                    'repository_class' => MyUserRepository::class,
                    'event_store' => MyCustomEventStore::class, // <-- Custom event store service id
                    'aggregate_type' => MyUser::class,
                    'aggregate_translator' => 'user_translator',
                    'disable_identity_map' => true,
                ],
            ],
        ],
    ],
]

Last but not least you can enable the so called "One-Stream-Per-Aggregate-Mode":

[
    'prooph' => [
        'event_sourcing' => [
            'aggregate_repository' => [
                'user_repository' => [
                    'repository_class' => MyUserRepository::class,
                    'aggregate_type' => MyUser::class,
                    'aggregate_translator' => 'user_translator',
                    'snapshot_store' => 'awesome_snapshot_store', // <-- SnapshotStore service id
                    'one_stream_per_aggregate' => true // <-- Enable One-Stream-Per-Aggregate-Mode
                ],
            ],
        ],
    ],
]
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky