Aggregate ID
The aggregate id
is a unique identifier for an aggregate.
It is used to identify the aggregate in the event store.
The aggregate
does not care how the id is generated,
since only an aggregate-wide unique string is expected in the store.
This library provides you with a few options for generating the id.
Warning
Performance reasons, the default configuration of the store require an uuid string for aggregate id
.
But technically, for the library, it can be any string.
If you want to use a custom id, you have to change the aggregate_id_type
in the store configuration.
Uuid
The easiest way is to use an uuid
as an aggregate ID.
For this, we have the Uuid
class, which is a simple wrapper for the ramsey/uuid library.
You can use it like this:
use Patchlevel\EventSourcing\Aggregate\BasicAggregateRoot;
use Patchlevel\EventSourcing\Aggregate\Uuid;
use Patchlevel\EventSourcing\Attribute\Aggregate;
use Patchlevel\EventSourcing\Attribute\Id;
#[Aggregate('profile')]
final class Profile extends BasicAggregateRoot
{
#[Id]
private Uuid $id;
}
use Patchlevel\EventSourcing\Aggregate\Uuid;
$uuid = Uuid::generate();
$uuid = Uuid::fromString('d6e8d7a0-4b0b-4e6a-8a9a-3a0b2d9d0e4e');
Note
We implemented the version 7 of the uuid, because it is most suitable for event sourcing. More information about uuid versions can be found here.
Custom ID
If you don't want to use an uuid, you can also use the custom ID implementation. This is a value object that holds any string.
use Patchlevel\EventSourcing\Aggregate\BasicAggregateRoot;
use Patchlevel\EventSourcing\Aggregate\CustomId;
use Patchlevel\EventSourcing\Attribute\Aggregate;
use Patchlevel\EventSourcing\Attribute\Id;
#[Aggregate('profile')]
final class Profile extends BasicAggregateRoot
{
#[Id]
private CustomId $id;
}
Warning
If you want to use a custom id that is not an uuid,
you need to change the aggregate_id_type
to string
in the store configuration.
More information can be found here.
So you can use any string as an id:
Implement own ID
Or even better, you create your own aggregate-specific ID class. This allows you to ensure that the correct id is always used. The whole thing looks like this:
use Patchlevel\EventSourcing\Aggregate\AggregateRootId;
class ProfileId implements AggregateRootId
{
private function __construct(
private readonly string $id,
) {
}
public function toString(): string
{
return $this->id;
}
public static function fromString(string $id): self
{
return new self($id);
}
}
use Patchlevel\EventSourcing\Aggregate\BasicAggregateRoot;
use Patchlevel\EventSourcing\Attribute\Aggregate;
use Patchlevel\EventSourcing\Attribute\Id;
#[Aggregate('profile')]
final class Profile extends BasicAggregateRoot
{
#[Id]
private ProfileId $id;
}
AggregateRootId
interface yourself.
Here for the uuid:
use Patchlevel\EventSourcing\Aggregate\AggregateRootId;
use Patchlevel\EventSourcing\Aggregate\RamseyUuidV7Behaviour;
class ProfileId implements AggregateRootId
{
use RamseyUuidV7Behaviour;
}
use Patchlevel\EventSourcing\Aggregate\AggregateRootId;
use Patchlevel\EventSourcing\Aggregate\CustomIdBehaviour;
class ProfileId implements AggregateRootId
{
use CustomIdBehaviour;
}