What do you think about introducing some standards regarding CQRS and Event sourcing?
I have a working/in production web based CRM application that uses one of my micro-frameworks <https://github.com/xprt64/cqrs-es> . It uses the command handler style described on cqrs.nu, where command handlers are aggregate methods. The aggregate is identified by the ID (extracted from Command) and class (manually/automatically subscribed). The normal flow is this (the flow implemented by my DefaultCommandDispatcher ): - the client code (i.e. a REST endpoint) creates a new Command and it sends the command to the CommandDispatcher - the CommandDispatcher identifies the aggregate class (using CommandSubscriber) and ID (using Command::getAggregateId) then creates a new aggregate instance - it rehydrates the aggregate from the event store (by loading all the prior events and applying them to the aggregate instance) - it calls the aggregate's command method (identified by using CommandSubscriber) and collects the yielded events (also it applies them onto the aggregate itself, one by one, at collect time - a kind of reactive aggregate); - it persists the collected events to the EventStore, FutureEventsStore or ScheduledCommandStore depending on the yielded message type - it notifies the event handlers using EventDispatcher - it discards the aggregate The aggregate should not inherit from anything and nothing should be injected into it. It should remain pure, side effect free. Any side effect should be observed by its yielded events. I like this style because it reduces a lot of code duplication found in the other style (command handler being in the Application layer) where almost every command handler looks the same: it loads the Events from the store using a Repository, it factories a new Aggregate, it rehydrates the Aggregate (by applying the events to the Aggregate), it calls a method on the aggregate, it collects the events, it persists the events and then notify all subscribers (event handlers). In cqrs.nu's style this entire algorithm can be extracted in a CommandDispatcher. So, I propose (at least) the following interfaces (in the namespace Cqrs) //events interface Event; interface EventDispatcher; interface EventSubscriber; interface MetadataFactory; interface EventStore; interface AggregateEventStream extends EventStream; interface EventStream extends \IteratorAggregate; interface EventStreamGroupedByCommit extends EventStream; //commands interface Command; interface CommandDispatcher; //can be decorated by a CommandDispatcherWithCommandValidation interface CommandSubscriber; interface MetadataWrapper; interface CommandValidatorSubscriber; //used by CommandDispatcherWithCommandValidation //scheduling interface FutureEventsStore interface ScheduledCommand extends Command, ScheduledMessage; interface ScheduledEvent extends ScheduledMessage interface ScheduledMessage extends IdentifiedMessage; interface IdentifiedMessage; interface CommandScheduler; interface ScheduledCommandStore; //read models and sagas (process managers) interface ReadModelInterface; interface SagaEventTrackerRepository; I know that there are a lot of interfaces, but in fact, in a working application, more interfaces are needed. In order for this to work, the minimal requirements from the code in the Domain layer is the Command interface (for its getAggregateId method). The Event interface should be used only to detect event handlers by reflection. So, the domain code remains (almost) pure. I have a todo <https://github.com/xprt64/todosample-cqrs-es> example on github if you want to learn more. I know that my question mixes the proposed standard with my implementation but I don't know how to start the discussion otherwise. So, what do you think? -- You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group. To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+unsubscr...@googlegroups.com. To post to this group, send email to php-fig@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/0c9a062b-4f1b-4f3c-85d3-433a93fdb234%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.