Prooph Snapshot Serializer

Recently version many of prooph's components were updated to a new mayor release. One of its components is the prooph/snapshot-store able to serialize, and persist aggregates so they do not have to be reconstituted from the event stream when they are needed again.

A missing feature was the ability to use a different serializer/deserializer. It turned out to be relatively simple to implement it in such a way with backward compatible. All you have to do to change the following;

Both the PdoSnapshotStore and MongoSnapshotStore are now capable of consuming a Serializer which takes care of serialization/unserialization;

interface Serializer
{
    public function serialize($data): string;
    public function unserialize(string $data);
}

A default Serializer is implemented as CallbackSerializer which will use the build-on serialize/unserialize method of PHP. Simply instantiate it with different callbacks to change it's default behavior.

$connection = new PDO(...);
$tableMap = [];
$tableName = 'snapshots';
$serializer = new CallbackSerializer('igbinary_serialize', 'igbinary_unserialize');

$snapshotStore =  new PdoSnapshotStore(
    $connection,
    $tableMap,
    $tableName,
    $serializer
);

If you prefer to use a psr/container driven application you simply need to create a factory for the Serializer interface;

class SerializerFactory
{
    public function __invoke(ContainerInterface $container): Serializer
    {
        return new CallbackSerializer(function ($data) {
            return gzdeflate(serialize($data), 9);
        }, function ($data) {
            return unserialize(gzinflate($data));
        });
    }
}

the declare a dependency for the factory;

return [
    'dependencies' => [
        'factories' => [
            Serializer::class => SerializerFactory::class,
        ],
    ], 

and add a key to the snapshot configuration;

return [
    'prooph' => [
        'pdo_snapshot_store' => [
            'default' => [
                'connection_service' => 'pdo.connection',
                'serializer' => Serializer::class
            ],
        ],

Do not forget to clear existing snapshots and reset running snapshot projectors.