Dispatching Events
Events PHP
Previous pages provide the background on how to handle event messages in your application. The dispatching process is the starting point for event message.
You will mostly send events after successfully handling Command Message, examples will base on that assumption.
You can inject EventBus and send events wherever necessary. Ecotone tries not to impose any specific solutions.
Event Bus
is special type of Messaging Gateway. namespace Ecotone\Modelling;
interface EventBus
{
// 1
public function publish(object $event, array $metadata = []) : void;
// 2
public function publishWithRouting(string $routingKey, mixed $event = [], string $eventMediaType = MediaType::APPLICATION_X_PHP, array $metadata = []) : void;
}
Event is routed to the Handler by class type.
Command Handler
class CloseTicketCommandHandler
{
#[CommandHandler]
public function closeTicket(CloseTicketCommand $command, EventBus $eventBus) : void
{
$eventBus->publish(new TicketWasClosed($command->getTicketId()));
}
}
Event Handler
class NotificationService
{
#[EventHandler]
public function closeTicket(TicketWasClosed $event) : void
{
// notify about closing the ticket
}
}
Is used with
Command Handlers,
routed by name and converted using Converter if needed.
Sending events by name instead of class type, may be found useful in integration with external application, when events are in different Media Type than PHP class. Command Handler
class CloseTicketCommandHandler
{
#[CommandHandler]
public function closeTicket(CloseTicketCommand $command, EventBus $eventBus) : void
{
$eventBus->publishWithRouting(
"ticket.wasClosed",
'{"ticketId": 123}',
"application/json"
);
}
}
Event Handler
class NotificationService
{
#[EventHandler("ticket.wasClosed")]
public function closeTicket(TicketWasClosed $event) : void
{
// notify about closing the ticket
}
}
JSON will be automatically converted to specific
class type hinted
in method declaration of Event Handler. You could also use in here simple array
if you have JSON
to array
Converter or a string
, if you like to receive JSON string
.Ecotone
does provide possibility to automatically gather events from Aggregate
and publish them using EventBus.
To tell
Ecotone
, which method it should use for retrieving Event objects when using State-Stored Aggregate mark method containing events with annotation @AggregateEvents.
After handling Command
or Event
on Aggregate
events will be published. #[AggregateEvents]
public function getRecordedEvents() : array
Events will be automatically retrieved and published after handling Commands in your Aggregate.
You don't need to create your own method within aggregate, you may reuse
predefined trait
for that WithAggregateEvents
.#[Aggregate]
final class Order
{
use WithAggregateEvents;
public function __construct(
#[AggregateIdentifier] public readonly string $orderId
) {
$this->recordThat(new OrderWasPlaced($orderId));
}
#[CommandHandler]
public static function create(PlaceOrder $command)
{
return new self($command->orderId);
}
(...)
When using Event Sourcing Aggregate you do not need to do anything extra. Each method should return events after handling, those events will automatically published using
Event Bus.
#[CommandHandler]
public function deposit(DepositMoney $command): array
{
return [new MoneyWasDeposited($command->walletId, $command->amount)];
}
Events published from aggregate, are publish by class name and routing, if event is named.
#[NamedEvent("order_was_placed")]
class OrderWasPlaced
Last modified 1mo ago