Creating and configuring aggregates | 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/v6)  Using-aggregates  Creating and configuring aggregates

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

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

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

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

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

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

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

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

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

      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                                                                                                                                                                                                                                    `

Creating and configuring aggregates
===================================

###  On this page

1. [ Creating an aggregate ](#content-creating-an-aggregate)
2. [ Retrieving an aggregate ](#content-retrieving-an-aggregate)
3. [ Recording events ](#content-recording-events)
4. [ Persisting aggregates ](#content-persisting-aggregates)
5. [ Want to know more? ](#content-want-to-know-more)

An aggregate is a class that decides to record events based on past events.

Creating an aggregate
-----------------------------------------------------------------------------------------------------------------------

The easiest way to create an aggregate root would be to use the `make:aggregate` command:

```
php artisan make:aggregate MyAggregate
```

This will create a class like this:

```
namespace App\Aggregates;

use Spatie\EventSourcing\AggregateRoots\AggregateRoot;

class MyAggregate extends AggregateRoot
{
}
```

Retrieving an aggregate
-----------------------------------------------------------------------------------------------------------------------------

An aggregate can be retrieved like this:

```
MyAggregate::retrieve($uuid)
```

If you don't want to use the static retrieve method, you can also retrieve an aggregate on an initialized AggregateRoot like this:

```
$myAggregate = new MyAggregate();
$myAggregate->loadUuid($uuid);
```

The `load` method is handy when injecting aggretate roots in constructors or classes where method injection is supported.

```
public function handle(MyAggregate $aggregate) {
    $aggregate->load($uuid);

    // ...
}
```

This will cause all events with the given `uuid` to be retrieved and fed to the aggregate. For example, an event `MoneyAdded` will be passed to the `applyMoneyAdded` method on the aggregate if such a method exists.

Recording events
--------------------------------------------------------------------------------------------------------

Inside an aggregate you can record new events using the `recordThat` function. All events being passed to that function should implement `Spatie\EventSourcing\ShouldBeStored`.

Here's an example event

```
use Spatie\EventSourcing\StoredEvents\ShouldBeStored;

class MoneyAdded extends ShouldBeStored
{
    /** @var int */
    private $amount

    public function __construct(int $amount)
    {
        $this->amount = $amount;
    }
}
```

Inside an aggregate root you can pass the event to `recordThat`:

```
// somewhere inside your aggregate
public function addMoney(int $amount)
{
    $this->recordThat(new MoneyAdded($amount));
}
```

Calling `recordThat` will not persist the event to the DB, that will happen when the aggregate itself gets persisted. However, recording an event will cause it getting applied to the aggregate immediately. For example, when you record the event `MoneyAdded`, we'll immediately call `applyMoneyAdded` on the aggregate.

Notice that your event isn't required to contain the `$uuid`. Your aggregate is built up for a specific `$uuid` and under the hood, the package will save that `$uuid` along with the event when the aggregate gets persisted.

Persisting aggregates
-----------------------------------------------------------------------------------------------------------------------

To persist an aggregate call `persist` on it. Here's an example:

```
MyAggregate::retrieve($uuid) // will cause all events for this uuid to be fed to the `apply*` methods
   // call methods that record events
   ->persist(); //
```

Persisting an aggregate root will write all newly recorded events to the database. The newly persisted events will get passed to all projectors and reactors.

By default, the event won't be fired on Laravels event bus. To dispatch events when they are stored, you can set the `dispatch_events_from_aggregate_roots` value in the `event-sourcing` config file to `true`.

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

Aggregate roots are a crucial part in large applications. Our course, [Event Sourcing in Laravel](https://event-sourcing-laravel.com/) covers them in depth:

- 9. Aggregate Roots
- 10. State Management in Aggregate Roots
- 11. Aggregate Partials
- 12. State Machines with Aggregate Partials
