Meeting between Basti (@bwaidelich) and Robert (@robert) regarding the Neos CQRS / ES packages.
Basti went through some slides of his presentation from the Neos Devcamp which outline the minimal flow of commands and events.
Question: do we actually need to support / implement a Command Bus?
The reason for having a Command Bus is supposedly only for deferring execution of commands to remote applications or redirecting commands to other channels. Some people (Greg Young …) consider execution of remote commands as a wrong design decision, so if we restrict ourselves to only execute commands locally and interact with remote applications through events, we might have an easier time and a more simple code base.
Question: Aggregates usually replay all events in order to reconstitute their (PHP-) object. Can that be optimized?
Many operations of an aggregate don’t even need the aggregate’s state. And events don’t need to be replayed, if we implement a clever snapshot-mechanism, basically working like a projection. We’ll need the version information in order to install some optimistic locking.
-> Basti says: letting repo collect events and then publish them may be overhead, rather let’s Aggregate methods return an event directly
-> Robert: but what about creating new Aggregates?
$user = User::signUp($firstName, $lastName);
-> Robert: since Repositories need to have an Identity Map anyway, they can as well have a Unit of Work which collects events, or we let the Aggregate publish events directly (synchronously):
UserAggregate {
protected $name;
public function rename($newName) {
$this->recordThat(UserRenamed::occur($this->identifier, [‘oldName’ => $this->name, ‘name’ => $newName ]);
// -> calls $this->eventBus->publishEvent($userRenamed)
// -> calls $this->onRenamed()
}
protected function onRenamed($even) {
$this->name = $event->newName;
}
-> Basti: the Event should only contain the domain-relevant payload, but it must be possible to add additional meta data (enrich the event) which adds information about the user who triggered the event, her IP address and so on.
We agree on that a user (developer) should be made aware of that he’s dealing with events, and should have control over when events are published. A dev shouldn’t get the impression that this is just a variation of Flow’s current persistence mechanism.
Regarding the current Neos CQRS / ES packages (on Github):
We all (Basti, Dominique, Robert) need an ES / CQRS solution urgently, so one option is to work on our individual code bases in parallel. But it’s also a waste of resources, so let’s try to get closer to a common solution next Friday.
Basti and Robert: the current implementation (by Dominique) already has too many extension points (interfaces …) and focusses a lot on Event Store internals. Let’s try to rather create a basic but working ES / CQRS solution first and avoid bells and whistles wherever we can. For that we need, of course, to identify the essential API so we don’t need to refactor it later on.
Robert: will go through Dominique’s code this week, probably fork and adjust it, and try to refactor some commands / events of his Beach application to get a feeling for it.