Event Sourcing Aggregate

This chapter will cover the basics on how to implement an Aggregate. For more details on what an Aggregate is read the DDD and CQRS concepts page.

Event Sourcing Aggregate

Event Sourced Aggregate instead of storing newest state, stores all the events that happened within specific aggregate.

/**
* @Aggregate() // 1
*/
class Ticket
{
/**
* @AggregateIdentifier() // 1
*/
private string $ticketId;
private string $workerId;
/**
* @CommandHandler() // 2
*/
public static function start(StartTicketCommand $command) : array
{
return [new TicketWasStartedEvent($command->getTicketId())];
}
/**
* @CommandHandler() // 2
*/
public function assignWorker(AssignWorkerCommand $command) : array
{
$event = new WorkerWasAssignedEvent($this->ticketId, $command->getWorkerId());
$this->applyWorkerWasAssigned($event);
return [$event];
}
private function applyTicketWasStarted(TicketWasStartedEvent $event) : void
{
$this->ticketId = $event->getTicketId();
}
private function applyWorkerWasAssigned(WorkerWasAssignedEvent $event) : void
{
$this->workerId = $event->getAssignedWorkerId();
}
/**
* @AggregateFactory() // 3
*/
public static function createFrom(array $events) : self
{
$self = new self();
foreach ($events as $event) {
switch (get_class($event)) {
case TicketWasStartedEvent::class: {
$self->applyTicketWasStarted($event);
break;
}
case WorkerWasAssignedEvent::class: {
$self->applyWorkerWasAssigned($event);
break;
}
}
}
return $self;
}
}
  1. @Aggregate and @AggregateIdentifier works exactly the same as State-Stored Aggregate.

  2. @CommandHandlerfor event sourcing returns events generated by specific method. This will be passed to the Repository as new state.

  3. @AggregateFactory is static method responsible for reconstructing Aggregate from previously created events. @CommandHandler will be called for instance returned by this method.