A prooph Event Store can be expanded using plugins. Some plugins are provided by prooph but you can write your own ones to customize the event store using event hooks.
Requirements: an event store wrapped with Prooph\EventStore\ActionEventEmitterEventStore
.
Action events are triggered when methods of the event store are invoked. The action events are named like the event store methods. The following events are available (event target is always the event store):
create
: event params: stream
- result params: streamExistsAlready
appendTo
: event params: streamName
, streamEvents
- result params: streamNotFound
, concurrencyException
load
: event params: streamName
, fromNumber
, count
, metadatamatcher
- result params: streamEvents
, streamNotFound
loadReverse
: event params: streamName
, fromNumber
, count
, metadatamatcher
- result params: streamEvents
, streamNotFound
delete
: event params: streamName
- result params: streamNotFound
hasStream
: event params: streamName
- result params: result
fetchStreamMetadata
: event params: streamName
- result params: metadata
, streamNotFound
updateStreamMetadata
: event params: streamName
, metadata
- result params: streamNotFound
fetchStreamNames
: event params: filter
, metadataMatcher
, limit
, offset
- result params: streamNames
fetchStreamNamesRegex
: event params: filter
, metadataMatcher
, limit
, offset
- result params: streamNames
fetchCategoryNames
: event params: filter
, offset
, limit
- result params: categoryNames
fetchCategoryNamesRegex
: event params: filter
, offset
, limit
- result params: categoryNames
If the event store implements \Prooph\EventStore\TransactionalActionEventEmitterEventStore, the following additional events are available:
beginTransaction
: event params: none - result params: transactionAlreadyStarted
commit
: event params: none - result params: transactionNotStarted
rollback
: event params: none - result params: `transactionNotStartedIf you took a look at the quick start, you should already be familiar with the possibility to attach an event listener plugin.
$eventStore->attach(
'commit',
function (\Prooph\Common\Event\ActionEvent $actionEvent) {
//plugin logic here
},
1000 // priority
);
More complex plugins are typically provided as classes with their own dependencies. A plugin can implement the Prooph\EventStore\Plugin\Plugin
interface
and can then attach itself to the event store in the Plugin::attachToEventStore($eventStore)
method.
Implementing the interface is especially useful when you use the event store factory.
The event-driven system opens the door for customizations. Here are some ideas of what you can do with it:
create
and appendTo
eventcausation id
(id of the command which caused the event)transaction
, commit
and rollback
eventsBy default, the component is shipped with a plugin to automatically add metadata to each event. For instance, you may want to add information about the command which caused the event or even the user who triggered that command.
Here is an example of its usage:
<?php
use Prooph\Common\Messaging\Message;
use Prooph\EventStore\Metadata\MetadataEnricher;
use Prooph\EventStore\Metadata\MetadataEnricherAggregate;
use Prooph\EventStore\Metadata\MetadataEnricherPlugin;
class IssuerMetadataEnricher implements MetadataEnricher
{
// ...
public function enrich(Message $event): Message
{
if ($this->currentUser) {
$event = $event
->withAddedMetadata('issuer_type', 'user')
->withAddedMetadata('issuer_id', $this->currentUser->id());
}
return $event;
}
}
$plugin = new MetadataEnricherPlugin(new MetadataEnricherAggregate([
$issuerMetadataEnricher,
$causationMetadataEnricher,
$otherMetadataEnricher,
]));
$plugin->attachToEventStore($eventStore);
All internal metadata is prefixed with _
(underscore), f.e. _causation_id
. Do not use metadata keys starting with an
underscore, as this is reserved for prooph internals.
The event store interface is divided into read-only methods, see Prooph\EventStore\ReadOnlyEventStore
and write methods
see Prooph\EventStore\EventStore
. This distinction is useful in situations where you want to enforce ready-only access to
the event store.
In case you need a read only event store, you can wrap your existing event store implementation with the ReadOnlyEventStoreWrapper.
$readOnlyEventStore = new ReadOnlyEventStoreWrapper($eventStore);