Download the PHP package xprt64/dudulina without Composer
On this page you can find all versions of the php package xprt64/dudulina. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download xprt64/dudulina
More information about xprt64/dudulina
Files in xprt64/dudulina
Package dudulina
Short Description CQRS with Event Sourcing mini framework for PHP
License proprietary
Informations about the package dudulina
CQRS + Event Sourcing library for PHP 7+
This is a non-obtrusive CQRS + Event Sourcing library that helps building complex DDD web applications.
Minimum dependency on the library in the domain code
Only 3 interfaces need to be implemented
No inheritance! Your domain code remains clean and infrastructure/framework agnostic as should be.
-
\Dudulina\Event
for each domain event; no methods, it is just a marker interface; the domain events need to be detected by the automated code generation tools; -
\Dudulina\Command
for each domain command; only one method,getAggregateId()
; it is needed by the command dispatcher to know that Aggregate instance to load from Repository \Dudulina\ReadModel\ReadModelInterface
for each read model; this is required only if you use theReadModelRecreator
to rebuild your read-models (projections)
Even if only a few interfaces need to be implemented, you could loose the coupling to the library even more. You could define and use your own domain interfaces and only that interfaces would inherit from the library interfaces. In this way, when you change the library, you change only those interfaces.
Minimum code duplication on the write side
On the write side, you only need to instantiate a command and send it to the CommandDispatcher
;
Let's create a command.
Now, let's create a simple event:
Somewhere in the UI or Application layer:
That's it. No transaction management, no loading from the repository, nothing. The command arrives to the aggregate's command handler, as an argument, like this:
The read models receive the raised event to. They process the event after it is persisted. Take a look at a possible read model:
The Read-models can be updated in a separate process, in realtime-like (by tailing) or by polling the Event store or even using JavaScript. Read more here about how you can keep the Read-model up-to-date.
So, when a command is dispatched the following things happen:
- the aggregate class is identified
- the aggregate is loaded from the repository, replaying all previous events
- the command is dispatched to the aggregate instance
- the aggregate yields the events
- the events are persisted to the event store
- the read-models are notified about the new events
- the sagas are notified also; if the sagas generate other commands, the loop is started again.
If an exception is thrown by the command handler on the aggregate, no events are persisted and the exception reach the caller
Read the entire documentation here
The Event store
There is a MongoDB implementation of the Event store and a Restful HTTP API for this Event store if you want to build Read-models in any other languages than PHP.
A JavaScript connector is also available. Here you can find some examples of updating a Read-model in JavaScript.
The Queries
The library can dispatch queries also. The Askers ask questions and the Answerers answser them.
The Askers ask question to the \Dudulina\Query\Asker
and the can receive the answer as return value or as callback on them
(the method $this->whenAnsweredXYZ
or the one marked with @QueryAsker
).
The Answerers answer questions at the $this->whenAskedXXX
or @QueryHandler
marked methods.
They can also answer a question when they know that the answer has changed and all the askers are notified, by calling \Dudulina\Query\Answerer::answer()
.
CQRS bindings
How does the library know what command handler to call when a command is dispatched? Or what read models to notify when a new event is published? The answer to all these questions is CQRS bindings.
Long story short, the tools analyze the domain code, detect the handlers and build a PHP file with all the bindings as classes.
Then you use those classes to configure the CommandDispatcher. The create_bindings.php
must be run every time the domain code changes.
Then you need to include the file create_bindings.php
to your index.php
usually after vendors/autoload.php
.
Sample application
A Todo list sample application can be found at github.com/xprt64/todosample-cqrs-es.
Querying an Aggregate in DDD
Read more about how to query an Aggregate in order to test if a command will succeed or not, without actually executing it.
Questions?
Feel free to post to this group: https://groups.google.com/forum/#!forum/cqrs--event-sourcing-for-php.
All versions of dudulina with dependencies
psr/container Version ^1.0
xprt64/types Version ^1.0
xprt64/iterator Version ^1.0
psr/log Version ^1.0
xprt64/code-analysis Version ^1.1.15
xprt64/selector Version ^0.0.3