Using your own event serializer | laravel-event-sourcing | Spatie       

 SPATIE  

  Laravel Event Sourcing 
=========================

spatie.be/open-source

  [Docs](https://spatie.be/docs)  [Laravel-event-sourcing](https://spatie.be/docs/laravel-event-sourcing/v7)  Advanced-usage  Using your own event serializer

 Version   v7   v6   v5   v4   v3   v2   v1      

 Other versions for crawler [v7](https://spatie.be/docs/laravel-event-sourcing/v7) [v6](https://spatie.be/docs/laravel-event-sourcing/v6) [v5](https://spatie.be/docs/laravel-event-sourcing/v5) [v4](https://spatie.be/docs/laravel-event-sourcing/v4) [v3](https://spatie.be/docs/laravel-event-sourcing/v3) [v2](https://spatie.be/docs/laravel-event-sourcing/v2) [v1](https://spatie.be/docs/laravel-event-sourcing/v1) 

  Using your own event serializer    
- [ Introduction ](https://spatie.be/docs/laravel-event-sourcing/v7/introduction)
- [ Support us ](https://spatie.be/docs/laravel-event-sourcing/v7/support-us)
- [ Requirements ](https://spatie.be/docs/laravel-event-sourcing/v7/requirements)
- [ Installation &amp; setup ](https://spatie.be/docs/laravel-event-sourcing/v7/installation-setup)
- [ Questions and issues ](https://spatie.be/docs/laravel-event-sourcing/v7/questions-issues)
- [ Changelog ](https://spatie.be/docs/laravel-event-sourcing/v7/changelog)
- [ Upgrading ](https://spatie.be/docs/laravel-event-sourcing/v7/upgrading)
- [ Resources and alternatives ](https://spatie.be/docs/laravel-event-sourcing/v7/resources-and-alternatives)
- [ About us ](https://spatie.be/docs/laravel-event-sourcing/v7/about-us)

Getting familiar with event sourcing
------------------------------------

- [ Introduction ](https://spatie.be/docs/laravel-event-sourcing/v7/getting-familiar-with-event-sourcing/introduction)
- [ The traditional application ](https://spatie.be/docs/laravel-event-sourcing/v7/getting-familiar-with-event-sourcing/the-traditional-application)
- [ Using projectors to transform events ](https://spatie.be/docs/laravel-event-sourcing/v7/getting-familiar-with-event-sourcing/using-projectors-to-transform-events)
- [ Using aggregates to make decisions based on the past ](https://spatie.be/docs/laravel-event-sourcing/v7/getting-familiar-with-event-sourcing/using-aggregates-to-make-decisions-based-on-the-past)

Using projectors
----------------

- [ Writing your first projector ](https://spatie.be/docs/laravel-event-sourcing/v7/using-projectors/writing-your-first-projector)
- [ Creating and registering projectors ](https://spatie.be/docs/laravel-event-sourcing/v7/using-projectors/creating-and-configuring-projectors)
- [ Making sure events get handled in the right order ](https://spatie.be/docs/laravel-event-sourcing/v7/using-projectors/making-sure-events-get-handled-in-the-right-order)
- [ Thinking in events ](https://spatie.be/docs/laravel-event-sourcing/v7/using-projectors/thinking-in-events)

Using reactors
--------------

- [ Writing your first reactor ](https://spatie.be/docs/laravel-event-sourcing/v7/using-reactors/writing-your-first-reactor)
- [ Creating and configuring reactors ](https://spatie.be/docs/laravel-event-sourcing/v7/using-reactors/creating-and-configuring-reactors)

Using aggregates
----------------

- [ Writing your first aggregate ](https://spatie.be/docs/laravel-event-sourcing/v7/using-aggregates/writing-your-first-aggregate)
- [ Creating and configuring aggregates ](https://spatie.be/docs/laravel-event-sourcing/v7/using-aggregates/creating-and-configuring-aggregates)
- [ Testing aggregates ](https://spatie.be/docs/laravel-event-sourcing/v7/using-aggregates/testing-aggregates)
- [ Snapshots ](https://spatie.be/docs/laravel-event-sourcing/v7/using-aggregates/snapshots)

Advanced usage
--------------

- [ Preparing events ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/preparing-events)
- [ Replaying events ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/replaying-events)
- [ Storing metadata ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/storing-metadata)
- [ Handling exceptions ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/handling-exceptions)
- [ Discovering projectors and reactors ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/discovering-projectors-and-reactors)
- [ Using your own event storage model ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/using-your-own-event-storage-model)
- [ Using your own event storage repository ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/using-your-own-event-storage-repository)
- [ Using your own event serializer ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/using-your-own-event-serializer)
- [ Using aliases for stored event classes ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/using-aliases-for-stored-event-classes)
- [ Adding and Removing Projectors and Reactors ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/adding-and-removing-projectors-and-reactors)
- [ Aggregate Partials ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/aggregate-partials)
- [ Event Queries ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/event-queries)
- [ Commands ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/commands)

 Using your own event serializer
===============================

###  On this page 

1. [ Reusing a custom serializer ](#content-reusing-a-custom-serializer)
2. [ Upgrading Events ](#content-upgrading-events)
3. [ Want to know more? ](#content-want-to-know-more)

Events will be serialized by the `Spatie\EventSourcing\EventSerializers\JsonEventSerializer`. Like the name implies, this class can serialize an event to json so it can be easily stored in a `json` column in the database.

You can specify your own serializer by creating a class that implements `Spatie\EventSourcing\EventSerializers\EventSerializer` and specifying the class in the `event_serializer` key of the `event-sourcing.php` config file.

The default `JsonEventSerializer` is registered as a singleton, so the same instance and its normalizers are reused for every event resolved through the `EventSerializer` interface. Custom normalizers must not retain event-specific state between calls. In long-running workers, this instance lives for the lifetime of the application.

By default, custom serializers configured via `event_serializer` retain their transient binding: a new instance is created each time the interface is resolved. Serializers selected via an event's `#[EventSerializer]` attribute are resolved separately and are not made singletons by this binding.

This is the content of the `EventSerializer` interface:

```
namespace Spatie\EventSourcing\EventSerializers;

use Spatie\EventSourcing\ShouldBeStored;

interface EventSerializer
{
    public function serialize(ShouldBeStored $event): string;

    public function deserialize(string $eventClass, string $json, int $version, ?string $metadata = null): ShouldBeStored;
}
```

Reusing a custom serializer
-----------------------------------------------------------------------------------------------------------------------------------------

If your custom serializer and its normalizers keep no event-specific state, you can opt into singleton reuse too. On Laravel versions that support the [`#[Singleton]` attribute](https://laravel.com/docs/container#singleton-attribute), add it to your serializer class:

```
namespace App\EventSerializers;

use Illuminate\Container\Attributes\Singleton;
use Spatie\EventSourcing\EventSerializers\JsonEventSerializer;

#[Singleton]
class CustomEventSerializer extends JsonEventSerializer
{
}
```

Set `event_serializer` to `App\EventSerializers\CustomEventSerializer::class`. Laravel will reuse the same custom serializer instance when the package resolves the `EventSerializer` interface. The attribute also applies when the class is resolved directly, such as through an event's `#[EventSerializer]` attribute.

Alternatively, including on Laravel versions without the attribute, register the interface as a singleton in your application's service provider:

```
use App\EventSerializers\CustomEventSerializer;
use Spatie\EventSourcing\EventSerializers\EventSerializer;

$this->app->singleton(EventSerializer::class, CustomEventSerializer::class);
```

As with the default serializer, a singleton custom serializer and its normalizers live for the lifetime of the application, including across jobs in long-running workers.

Upgrading Events
--------------------------------------------------------------------------------------------------------

If an event payload has changed overtime, old events can be "upgraded" to the new payload on the fly in the event serializer.

Using our larabank example, let's imagine that we've gone international and our new accepting international payments. Our `MoneyAdded` events will need to have an additional field for the currency.

```
use App\Events\MoneyAdded;

class UpgradeSerializer extends JsonEventSerializer
{
    public function deserialize(string $eventClass, string $json, int $version, ?string $metadata = null): ShouldBeStored
    {
        $event = parent::deserialize($eventClass, $json, $version, $metadata);

        // all currency was USD before we started accepting other currencies
        if ($eventClass === MoneyAdded::class && empty($event->currency)) {
            $event->currency = 'USD';
        }

        return $event;
    }
}
```

Want to know more?
------------------------------------------------------------------------------------------------------------

Our course, [Event Sourcing in Laravel](https://event-sourcing-laravel.com/) covers this topic in depth:

- 18. Event Versioning

 A good
match?
-------------

### What we do best

- All things Laravel
- Custom frontend components
- Building APIs
- AI-powered features
- Simplifying things
- Clean solutions
- Integrating services

### Not our cup of tea

- WordPress themes
- Cutting corners
- Free mockups to win a job
- "Just execute the briefing"

 In short: we'd like to be a **substantial part** of your project.

 [ Get in touch via email ](mailto:info@spatie.be?subject=A%20good%20match%21&body=Tell%20us%20as%20much%20as%20you%20can%20about%0A-%20your%20online%20project%0A-%20your%20planning%0A-%20your%20budget%0A-%20%E2%80%A6%0A%0AAnything%20that%20helps%20us%20to%20start%20straightforward%21)
