Links

Handling Aggregate Creation

New Aggregate may be initialized using factory method.
#[Aggregate]
class Ticket
{
#[AggregateIdentifier]
private string $ticketId;
#[Column(type: "string")]
private string $assignedTo;
#[CommandHandler("startTicket")]
public static function startTicket(StartTicket $command): static
{
$ticket = new self();
$ticket->id = $command->id;
$ticket->assignedTo = $command->assignedTo;
return $ticket;
}
}
After calling startTicket aggregate will be automatically stored.
Factory method is static method in the Aggregate class. You may have multiple factory methods if needed.

Redirected Aggregate Creation

There may be a cases however, that you would like to do some action in case aggregate already exists. This may be useful to simply API by exposing single method and to avoid handling if cases.
#[Aggregate]
class Ticket
{
#[AggregateIdentifier]
private string $ticketId;
#[Column(type: "string")]
private string $assignedTo;
#[CommandHandler("startTicket")]
public static function startTicket(StartTicket $command): static
{
$ticket = new self();
$ticket->id = $command->id;
$ticket->assignedTo = $command->assignedTo;
return $ticket;
}
#[CommandHandler("startTicket")]
public function changeTicket(StartTicket $command): void
{
$ticket->assignedTo = $command->assignedTo;
}
}
The second method is registered under same endpoint startTicket and is non static method. Ecotone in this case will try to load the aggregate and, if it find it it will call changeTicket method, otherwise startTicket will be called.
Redirected aggregate creation works the same for Event Sourced Aggregates. Take under consideration however that redirected creation works in case Command has identifier inside.
Redirected aggregate creation will only work when given Command is Class or Array