Reputation: 885
There are a lot of opinions out there in terms of CQRS with DDD and what makes up each component. I haven't began to look into Event Sourcing yet, so the list below doesn't include anything related to that. Although insight into ES would be interesting.
So far I have the following components with associated responsibilities (see below). I have inlined some questions in the points below.
REST Endpoints / Application
AggregateId orderId = AggregateId.get(); AggregateId userId = finder.findUserAggregateIdByEmail(email); dispatcher.fire( new CreateOrderCommand( orderId, userId, orderItems ) );
Command
new CreateOrderCommand( orderId, userId, orderItems );
Command Handler
Aggregate Factory
factory.createOrder( orderId, userId, orderItems );
Aggregate Root / Aggregates
order.cancel();
Domain Service
Repository
repo.load(orderId);
Event
new OrderCancelledEvent( orderId );
Event Handler
Saga
Finder
finder.findOrdersOnDate( date );
Infrastructure Services
Question
Is this an accurate summary of the components vs. responsibilities? What's missing and what should be moved around? I can update the list with relevant answers.
Upvotes: 11
Views: 2468
Reputation: 3428
Like you said, there are many opinions out there, and you need to filter them as most of the time people are giving opinions without any experience on the matter. CQRS is a big topic so I don't think that without prior experience you should jump into DDD and ES altogether. Services should be well contained and with well defined boundaries and if you follow these principle you'll be able to have different implementations in your domain, so start with just CQRS now and add DDD/ES to the following services once you have mastered CQRS.
I would advice you so start building the CQRS part of your architecture, a gateway for the commands and one for the queries because that is common and just on that there are so many decisions to be made:
Rest API
Message contracts/validation
Read models ...
and start implementing your service in a more traditional way without DDD, just using the repository pattern. When you start feeling confident then maybe you can jump into DDD in terms of aggregates and later on to ES. You can always change the initial services at a later stage.
My advice would be not to try to do it all at once, because you will fail; I have seen it happening many times before.
For example: Wait for OrderShipped and OrderReceived events => fire CancelOrderCommand Wait for OrderCancelled => fire order cancelled email
Sagas should not publish events (saga pattern), sagas aggregate events and submit commands. The fact that frameworks like NServiceBus allow sagas to publish events does not help, so be aware.
Single (read+write) Normalized Database Model: the Finder can call other Finders (across contexts) to satisfy nested objects
What other contexts you want to have in your read models?
Infrastructure Services
Deals with infrastructure: db access, send emails, message queues, etc
Not sure what you mean by this, but it sure does not look right. Message queue or database service??
Upvotes: 3