Cqrs Es with Broadway
-
- Create Event Domain class (
UserWasCreated
) - Class implements
Broadway\Serializer\Serializable
- Add 2 methods to deal this event:
Serialize
=> return arrayDeserialize
=> return Event Domain object
- Create Event Domain class (
-
- Create User Class with attributes and methods
- Extends from
Broadway\EventSourcing\EventSourcedAggregateRoot
- Extends from
- Add
getAggregateRootId
method with Aggregate Root Id - Add
create
factory function with functionality:- Create
User
instance - Call
apply
function with Event Domain instance filled
- Create
- Add
applyNameEventDomain
protected function- Get information from Event Domain
- Fill User object with data
- Create User Class with attributes and methods
-
- Add a new migration to create Event table (
Version20220317233829
)
- Add a new migration to create Event table (
-
- Call to
create
User model function - Call to
userStore
repository to store the event
- Call to
-
- Create
UserStoreRepository
to store User events - Repository extends
Broadway\EventSourcing\EventSourcingRepository
- Create 2 functions:
Store
=> store User eventGet
=> get User event
- Create
-
-
- Create
UserView
Model (copy methods and attributes from User model)- Extends
Broadway\ReadModel\SerializableReadModel
- Create constructor
- Add
serialize
anddeserialize
function (in this case, similar to User model) - Add
getId
to return UserId (method required bySerializableReadModel
)
- Extends
- Create
-
- Create
UserProjection
class- Listening Event Domains configured into this class
- Extends from
Broadway\ReadModel\Projector
- It has, for each event, one function with the name
applyNameEventDomain
(UserWasCreated
)- Receive
UserWasCreated
parameter/event - Call
UserRepository
to saveUserView
with Doctrine into database
- Receive
- Create
-
- Create a standard
UserRepository
withsave
function to storeUserView
model
- Create a standard
-
-
-
- Create
DomainEventHandler
to catch all events executed in Broadway event bus.- Implements
Broadway\EventHandling\EventListener
to catch events
- Implements
- Create
SendWelcomeEmailProcessManager
with Domain Event as parameter (UserWasCreated
) to send an email
- Create
-
- Add in
DomainEventHandler
implementation ofMessageSubscriberInterface
to catch all events published in named queued "events".- Implements
Symfony\Component\Messenger\Handler\MessageSubscriberInterface
to catch events - Add
getHandledMessages
method to get events from queue "events" - Add
__invoke
method to send this event to Symfony event bus
- Implements
- Create
DomainEventPublisher
to dispatch Asynchronous messages to RabbitMQ- Implements
EventListener
to catch Broadway events and save in array message variable (in memory) - Implements
EventSubscriberInterface
necessary to catch kernel events.- Create
getSubscribedEvents
to listen for theTERMINATE
event to ensure that the event has been persisted. - Create
publish
method to dispatch event in RabbitMQ.
- Create
- Implements
- Create
MessengerAsyncEventBus
where configure async event bus and send message.
- Add in
-
-
- If user table is truncated, it is possible to recovery all data across events stored.
- Create
RestoreUserCommand
to callReplayer
class to execute events - Create
Replayer
class where implementsEventVisitor
replayForEvent
method is called all events by type to recovery events.- Then,
doWithEvent
method is called with each event to restore
- Create
- If user table is truncated, it is possible to recovery all data across events stored.
Create a user storing event when user was created and saving in User MySql table
- Database container:
cd docker && make
- Create database structure:
bin/console doctrine:migrations:migrate
- Execute project:
make local
- Execute consumer:
bin/console messenger:consume events -vv
Import this curl to Postman application and execute:
curl --location --request POST 'https://localhost:8000/signup' \
--header 'Content-Type: application/json' \
--form '_name="Victor"' \
--form '_email="[email protected]"' \
--form '_password="password123"'