twanhaverkamp / event-storage-in-mongodb-with-php
Event Storage in MongoDB with PHP
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/twanhaverkamp/event-storage-in-mongodb-with-php
Requires
- php: ^8.3
- ext-mongodb: *
- mongodb/mongodb: ^2.1
- twanhaverkamp/event-sourcing-with-php: ^1.3
Requires (Dev)
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^11.5
- squizlabs/php_codesniffer: ^3.11
README
This package is a MongoDB implementation for the "Event Sourcing with PHP" library.
Table of Contents
Usage
Installation
Requirements:
- PHP 8.3 (or higher)
If you're using Composer in your project you can run the following command:
composer require composer require twanhaverkamp/event-storage-in-mongodb-with-php:^1.0
Implementation
Most PHP frameworks like Symfony and Laravel allows you to register classes as services; If you like, you can register this Event store where you bind it to the EventStoreInterface.
Connect with MongoDB
When constructing the Event Store you're required to pass an instance of the MongoDB client as first argument, an Event describer instance as second argument and your Database and Collection names as third and fourth arguments.
// ... use MongoDB\Client as MongoDbClient; use TwanHaverkamp\EventSourcingWithPhp\Event\EventDescriber; use TwanHaverkamp\EventStorageInMongoDbWithPhp\Event\EventStore; // ... $eventStore = new EventStore\MongoDb( new MongoDbClient(sprintf( 'mongodb://%s:%s@%s:%d', 'root', 'password', 'mongodb', 27017, )), new EventDescriber\KebabCase(), 'your-database-name', 'your-collection-name', ); // ...
An Event describer can be found in the "Event Sourcing with PHP" library, which is automatically installed whenever you install this package. You can create your own Describer if you like; just make sure it implements the EventDescriberInterface, which can also be found in the "Event Sourcing with PHP" library.
Event registration
In order for the Event Store to know which type of Events exist, you need to register them in the Event Store:
use TwanHaverkamp\EventSourcingWithPhp\Example; use TwanHaverkamp\EventStorageInMongoDbWithPhp\Event\EventStore; EventStore\MongoDb::register( Example\Event\InvoiceWasCreated::class, Example\Event\PaymentTransactionWasStarted::class, Example\Event\PaymentTransactionWasCompleted::class, Example\Event\PaymentTransactionWasCancelled::class, );
You have to register your Events before actually using the Event Store.
Event storage
When you pass an Aggregate to the save function it loops over its Events and for every Event it will insert
a new "document" for the constructed Database and Collection names.
Dependency injection
Laravel project
Create your own service provider when your working in a Laravel project to bind the MongoDB class to the EventStoreInterface:
namespace App\Providers; use Illuminate\Contracts\Foundation\Application; use Illuminate\Support\ServiceProvider; use MongoDB\Client as MongoDbClient; use TwanHaverkamp\EventSourcingWithPhp\Event\EventDescriber\KebabCase; use TwanHaverkamp\EventSourcingWithPhp\Event\EventStore\EventStoreInterface; use TwanHaverkamp\EventStorageInMongoDbWithPhp\Event\EventStore\MongoDb; class EventStoreServiceProvider extends ServiceProvider { public function register(): void { $this->app->singleton(EventStoreInterface::class, function (Application $app) { return new MongoDb( new MongoDbClient(sprintf( 'mongodb://%s:%s@%s:%d', config('mongodb.username'), config('mongodb.password'), config('mongodb.host'), config('mongodb.port'), )), new EventDescriber\KebabCase(), config('mongodb.database'), config('mongodb.collection'), }); } }
Symfony project
If you're working in a Symfony project, you can leverage it's built-in "autowire" mechanism
by registering the Event Store as a service in the services.yaml:
services: _defaults: bind: TwanHaverkamp\EventSourcingWithPhp\Event\EventDescriber\EventDescriberInterface: '@event.describer' TwanHaverkamp\EventSourcingWithPhp\Event\EventStore\EventStoreInterface: '@event_store.mongodb' # ... event.describer: class: TwanHaverkamp\EventSourcingWithPhp\Event\EventDescriber\KebabCase event_store.mongodb: class: TwanHaverkamp\EventStorageInMongoDbWithPhp\Event\EventStore\MongoDb arguments: $client: '@mongodb.client' $databaseName: '%env(string:MONGODB_DATABASE)%' $collectionName: '%env(string:MONGODB_COLLECTION)%' mongodb.client: class: MongoDB\Client arguments: $uri: '%env(string:MONGODB_URI)%' # ...