Alessandro Giannone
Alessandro Giannone

Reputation: 885

CQRS Component Roles and Responsibilities with a REST API

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

Command Handler

Aggregate Factory

Aggregate Root / Aggregates

Domain Service

Repository

Event

Event Handler

Saga

Finder

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

Answers (1)

MeTitus
MeTitus

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

Related Questions