Persistence stores
Nexus ships three persistence store implementations: an in-memory store for tests, a DBAL-backed store for production with any Doctrine-supported database, and a Doctrine ORM-backed store for projects that already use Doctrine entities.
Store overview
| Implementation | Package | Use case |
|---|---|---|
InMemoryEventStore / InMemorySnapshotStore / InMemoryDurableStateStore | nexus-persistence | Unit tests; state is lost on restart |
DbalEventStore / DbalSnapshotStore / DbalDurableStateStore | nexus-persistence-dbal | Production; any DBAL-supported database |
DoctrineEventStore / DoctrineSnapshotStore / DoctrineDurableStateStore | nexus-persistence-doctrine | Projects already using Doctrine ORM |
In-memory stores
The in-memory stores hold data in PHP arrays for the lifetime of the process. They implement the same interfaces as the durable stores, so test code is structurally identical to production code.
<?php
declare(strict_types=1);
use Monadial\Nexus\Persistence\Event\InMemoryEventStore;
use Monadial\Nexus\Persistence\Snapshot\InMemorySnapshotStore;
use Monadial\Nexus\Persistence\EventSourced\EventSourcedBehavior;
use Monadial\Nexus\Persistence\EventSourced\SnapshotStrategy;
$eventStore = new InMemoryEventStore();
$snapshotStore = new InMemorySnapshotStore();
$behavior = EventSourcedBehavior::create($persistenceId, $emptyState, $commandHandler, $eventHandler)
->withEventStore($eventStore)
->withSnapshotStore($snapshotStore)
->withSnapshotStrategy(SnapshotStrategy::everyN(5))
->toBehavior();
DBAL stores
Install the DBAL adapter:
composer require nexus-actors/nexus-persistence-dbal
The DBAL stores write to three tables: nexus_event_journal, nexus_snapshot_store, and nexus_durable_state. Create the schema using PersistenceSchemaManager:
<?php
declare(strict_types=1);
use Monadial\Nexus\Persistence\Dbal\Schema\PersistenceSchemaManager;
$schemaManager = new PersistenceSchemaManager($connection);
$schemaManager->createSchema();
Wire the stores:
<?php
declare(strict_types=1);
use Monadial\Nexus\Persistence\Dbal\DbalEventStore;
use Monadial\Nexus\Persistence\Dbal\DbalSnapshotStore;
use Monadial\Nexus\Persistence\Dbal\DbalDurableStateStore;
$eventStore = new DbalEventStore($connection);
$snapshotStore = new DbalSnapshotStore($connection);
$durableStore = new DbalDurableStateStore($connection);
The DBAL stores accept an optional MessageSerializer (defaults to PhpNativeSerializer). Pass a custom serializer to store events as JSON or use the Valinor-based mapper.
Doctrine stores
Install the Doctrine adapter:
composer require nexus-actors/nexus-persistence-doctrine
The Doctrine stores use three ORM entity classes (EventEntry, SnapshotEntry, DurableStateEntry) mapped to the same table names as the DBAL stores. Wire them with an EntityManagerInterface:
<?php
declare(strict_types=1);
use Monadial\Nexus\Persistence\Doctrine\DoctrineEventStore;
use Monadial\Nexus\Persistence\Doctrine\DoctrineSnapshotStore;
use Monadial\Nexus\Persistence\Doctrine\DoctrineDurableStateStore;
$eventStore = new DoctrineEventStore($entityManager);
$snapshotStore = new DoctrineSnapshotStore($entityManager);
$durableStore = new DoctrineDurableStateStore($entityManager);
The Doctrine stores use the same table names (nexus_event_journal, nexus_snapshot_store, nexus_durable_state) as the DBAL stores. You can mix store implementations — for example, use DoctrineEventStore with DbalSnapshotStore — provided both point at the same underlying database.
Choosing between DBAL and Doctrine
Use the DBAL stores when your project does not use Doctrine ORM or you want minimal dependencies. Use the Doctrine stores when you already have an EntityManager configured and want Doctrine's lifecycle events and schema tooling to manage the persistence tables.
See also
- Event sourcing — wiring stores via
EventSourcedBehavior. - Durable state — wiring
DurableStateStore. - Testing — using in-memory stores in deterministic tests.