Using projectors to transform events | 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/v2)  Getting-familiar-with-event-sourcing  Using projectors to transform events

 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)

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

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

- [ Introduction ](https://spatie.be/docs/laravel-event-sourcing/v2/getting-familiar-with-event-sourcing/introduction)
- [ The traditional application ](https://spatie.be/docs/laravel-event-sourcing/v2/getting-familiar-with-event-sourcing/the-traditional-application)
- [ Using projectors to transform events ](https://spatie.be/docs/laravel-event-sourcing/v2/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/v2/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/v2/using-projectors/writing-your-first-projector)
- [ Creating and registering projectors ](https://spatie.be/docs/laravel-event-sourcing/v2/using-projectors/creating-and-configuring-projectors)
- [ Making sure events get handled in the right order ](https://spatie.be/docs/laravel-event-sourcing/v2/using-projectors/making-sure-events-get-handled-in-the-right-order)
- [ Thinking in events ](https://spatie.be/docs/laravel-event-sourcing/v2/using-projectors/thinking-in-events)

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

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

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

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

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

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

      You are viewing the documentation for **an older version** of this package. You can check the version you are using with the following command:

 `                                    composer show spatie/laravel-event-sourcing                                                                                                                                                                                                                                    `

Using projectors to transform events
====================================

Let's build a bit further on the [Larabank example](https://github.com/spatie/larabank-traditional) mentioned in [the previous section](/laravel-event-sourcing/v1/getting-familiar-with-event-sourcing/the-traditional-application). The main drawback highlighted that example is the fact that when updating a value, we lose the old value. Let's solve that problem.

Instead of directly updating the value in the database, we could write every change we want to make as an event in our database.

  Here we write our first event in the database  ![](../../images/transform-01.svg)  When new events come in, we'll write them to the events table as well  ![](../../images/transform-02.svg)All events get passed to a class we call a projector. The projector transforms the events to a format that is handy to use in our app. In our Larabank example, the events table hold the info of the individual transactions like `MoneyAdded` and `MoneySubtracted`. A projector could build an `Accounts` table based on those transactions.

 ![](../../images/transform-03.svg)Imagine that you've already stored some events, and your first projector is doing its job creating that `Accounts` table. The bank director now wants to know on which accounts the most transactions were performed. No problem, we could create another projector that reads all previous events and adds the `MoneyAdded` and `MoneySubtracted` events to make projections.

 ![](../../images/transform-04.svg)This package can help you store native Laravel events in a `stored_events` table and create projectors that transform those events.

Here's our example app [Larabank rebuild with projectors](https://github.com/spatie/larabank-projectors). In [the `AccountsController`](https://github.com/spatie/larabank-projectors/blob/677777c0cb7fd2584b54073ac82c91e25fd07d2b/app/Http/Controllers/AccountsController.php#L20-L36) we're not going to directly modify the database anymore. Instead, the controller will call methods which will in [their turn fire off events](https://github.com/spatie/larabank-projectors/blob/677777c0cb7fd2584b54073ac82c91e25fd07d2b/app/Account.php#L15-L41). Our package will listen for those events (which implement the empty `ShouldBeStored` interface) and store them in the `stored_events` table. Those events will also get passed to [all registered projectors](https://github.com/spatie/larabank-projectors/blob/677777c0cb7fd2584b54073ac82c91e25fd07d2b/config/event-sourcing.php#L18-L20). The [`AccountsProjector`](https://github.com/spatie/larabank-projectors/blob/677777c0cb7fd2584b54073ac82c91e25fd07d2b/app/Projectors/AccountsProjector.php) will build the `Accounts` table using [a couple of events it listens for](https://github.com/spatie/larabank-projectors/blob/677777c0cb7fd2584b54073ac82c91e25fd07d2b/app/Projectors/AccountsProjector.php#L17-L20).

If you want to know more about projectors and how to use them, head over to [the `using-projectors` section](/laravel-event-sourcing/v1/using-projectors/writing-your-first-projector).
