Goalkeeper — the guardian of a correct execution of commands

You have probably encountered problems related to the proper management of command execution by an assigned handler. In this piece I will raise the subject of the goalkeeper, which enters the application and manages the traffic properly — all in relation to the most fashionable thing this season (as well as in the previous ones!) CQRS. The example that I will show is presented using PHP.

Patryk Woziński
Docplanner Tech
4 min readNov 14, 2018

--

Photo by Zan on Unsplash

Gate — the only door into our club

The gate is the place where all the commands run in our system meet. Regardless of whether they are synchronous or asynchronous actions, coming from REST API or CLI, this is where they meet and are verified by our goalkeeper before being allowed into the main part of the application (it’s very easy to see in the DDD approach).

Our gate is responsible for checking our guest (command) before it goes to the assigned handler under various conditions. One of them is to check if the command was not activated recently — thanks to this we will avoid flooding the application by sending huge numbers of malicious commands. Of course, we can make exceptions related to commands with logging their execution. It is also here we can conduct the application properly by transferring the execution of some batch of code to asynchronous, running in the background. A great example of such performance was presented in Sławek Sobótkas’ (working in Bottega IT Minds) presentation.

List of the last guests in the club and those who could not enter it

Another very important place is GateHistory. It is responsible for defining which commands were performed in the recent past (seconds, milliseconds, depending on our settings). I think the implementation of the store’s interface in the form of Redis will be great for this function. It is a very good and fast-to-use tool that is able to easily take over the traffic and properly document the application facts for individual commands.

Redis provides us with a number of functions that, of course, with the TTL assigned, can help us determine the appropriate permits or entry bans to the handler’s commands. It is worth getting acquainted with functions such as incrementing the hash under which we will hide the unique key for our command.

In addition, when our command fails to register, we can easily log in this information from the application layer level. What is more, having access to GateHistory we are able to very precisely define the course of the previous pre-operational operations and add information about their processing status.

Application launch environment

In a properly designed application based on the CQRS approach with segregation of the recording and reading model and the separation of commands and queries, we have the opportunity of creating one place where all our logic based on the command will be performed — I mean of course the class that will launch the right handler pulled from our HandlerProvider.

It is RunEnvironment, which depends on the handler locator described above and additional security features that we need, such as database transactions, error logging or even proper profiling of the application’s operation. The runtime environment is on when a command that was allowed by our access gateway is passed to it. It can be started both synchronously and non-synchronously after being removed from our queue. It is possible, thanks to these features, for the access gate to easily become a perfect place to divert control.

Additional layer at CQRS: why, oh why?!

Certainly there will be sceptics who will undermine the sense of introducing the Gate to the CQRS with a question: “Why do we need another layer, another abstraction in the approach, which is not easy anyway?” Yes, it’s true — we’re increasing the level of abstraction of our application layer, but we’re doing it with one very important intention. Thanks to the common access point, then — just as the name suggests — we have one and only one place through which we will send traffic from various possible points in the interface layer. Both the implementation of the cron, the manually typed command, receiving the request from RestAPI or sending a form or clicking the button on our front by the user — all this will be secured against unnecessary, repeated execution at a specific time interval. In addition, we will gain certainty and one place where we will manage transactions, log basic errors and gain the ability to easily manage commands.

I think creating one common place for command traffic from the whole application is a good idea. We gain incredible control that is worth keeping.

I attach a repository that presents a more complete implementation of the Gate along with related classes and interfaces below.

Link to the repository: https://github.com/patrykwozinski/cqrs-gate-example

--

--

Patryk Woziński
Docplanner Tech

Product Engineer with many years of experience in creating and designing web applications. #DDD freak