CQRS and Event Sourcing implementation in PHP (2/4)

3 min

read

In the first part of the article about CQRS and Event Sourcing implementation in PHP, I’ve focused on explaining what are CQRS and Event Sourcing. I’ve mentioned the general idea of CQRS, Event Sourcing and Event Store. Also, I’ve presented their pros and cons. The second part of the article is about the implementation of the Write Model with Broadway library.

Domain

Let’s imagine that you need to implement a module to handle users in an application. They need to be able to log in and browse through the list of all the registered users.

According to the idea presented in the first part of the article, you divide the app into two parts. First will be responsible for saving and managing the users, the other will be delivering a simple list which includes some basic data and enabling logging in.

Step-by-step implementation of the Write Model

So, your task is to implement a functionality which allows adding users to the repository. Let’s check what we need:

  • CreateUserCommand – a command to add a user,
  • CreateUserHandler – a handler to process a command,
  • UserWasCreatedEvent – an event which confirms a user creation,
  • UserAggregateRoot – a user domain object,
  • UserRepository – a repository to save an object.

CreateUserCommand

The command is a class containing only the fields which are necessary to create a user. You can compare it to a traditional request you submit in the office. This kind of request needs to be filled and passed to be processed.

CreateUserHandler

The handler is responsible for processing a request (CreateUserCommand). It’s a place where you can find the logic responsible for user creation.

Handler code looks like this:  

Please note that the class inherits from SimpleCommandHandler provided by Broadway. Thanks to that, you don’t have to call it – Broadway will do it for you. The only thing you have to do is to provide a proper method name (format: ‘handle’ + command name).

See also: Separating business logic in PHP

To create a user object, you need to use the factory method. It’ll create a domain object basing on the provided parameters. Of course, you save only a hash for the password, so the password needs to be encoded before passing through. The encoder is injected as a dependency to the handler. The last thing you have to do is to save a user using a repository which also has been injected as a dependency.

UserWasCreatedEvent

An event code looks like the one on an example below.

The object above informs you that the user has been created. It also contains its details. Here, you have another Broadway requirement – implementation of serialization/deserialization of an event. You have to do it on your own. The rest (save/read of the Event Store event) is done by Broadway.

User Aggregate Root

Aggregate Root objects have to extend a class  EventSourcedAggregateRoot.Thanks to that you get the possibility to apply events and to reconstitute objects from database.

Moreover, these objects have to meet a few additional requirements. First of all – you have to make sure that your object has its identifier. That’s why you have to implement getAggregateRootId() method.

Another requirement is to implement methods which are applying the proper event. Again, you have to provide a proper method name (format: ‘handle’ + event name).

See also: Switching framework and database tools in PHP

Please note that in a constructor, you can’t set any properties. You have to create a proper event, then it’ll be processed through the method applyUserWasCreatedEvent(). This solution enables applying the events to the object whilst recreating it from the Event Store. In the listing below, I purposely skipped accessors for private properties because I didn’t want to complicate the presented code. But obviously, they are needed in the final solution.

UserRepository

To fetch and save the data in the Event Store, you have to create a proper repository (EventSourcingRepository) which you can use in your class.

EventSourcingRepository requires you to provide a few arguments:

  • Event Store object,
  • Event Bus object,
  • a name of the class which will be operated (in the presented case it’s User),
  • a class of the object factory; I chose NamedConstructorAggregateFactory, which means the use of User class factory method instantiateForReconstitution(); then all the events will be applied,
  • eventStreamDecorators – an array of decorators which allow modifying events before saving them in the Event Store. You can add the metadata this way.

Additionally, I’ve created two methods to fetch the objects from the repository and save them in the same place.

It’s presented on the listing below.

This is how I’ve implemented the Write Model. Thanks to the use of Broadway, you don’t have to think about propagating the events. They will be put on Event Bus any time when a new event is saved by the repository. There they can be read by the read part of the app and used for the Read Model updates.

In the second part of CQRS and Event Sourcing implementation in PHP, I’ve focused on the implementation of the Write Model with Broadway library. The next part of the article will be about the implementation of the Read Model.

Estimate your project





Thanks

Thank you!

Your message has been sent. We’ll get back to you in 24 hours.

Back to page
24h

We’ll get back to you in 24 hours

to address your needs as quick as possible.

Estimation

We’ll prepare an estimation of the project

describing the team compostition, timeline and costs.

Code review

We’ll perform a free code review

if you already have an existing system or a part of it.

Our work was featured in:

Tech Crunch
Forbes
Business Insider

Aplikujesz do

The Software House

Aplikuj teraz

wyślij CV na adres: [email protected]

CopiedTekst skopiowany!

Nie zapomnij dodać klauzuli:

Kopiuj do schowka Copy

Jakie będą kolejne kroki?

Phone

Rozmowa telefoniczna

Krótka rozmowa o twoim doświadczeniu,
umiejętnościach i oczekiwaniach.

Test task

Zadanie testowe

Praktyczne zadanie sprawdzające dokładnie
poziom twoich umiejętności.

Meeting

Spotkanie w biurze

Rozmowa w biurze The Software House,
pozwalająca nam się lepiej poznać.

Response 200

Response 200

Ostateczna odpowiedź i propozycja
finansowa (w ciągu kilku dni od spotkania).

spinner