Geeks With Blogs

News


Dylan Smith ALM / Architecture / TFS

I’ve been doing a lot of learning on CQRS and Event Sourcing over the last little while and I have a number of questions that I haven’t been able to answer.

1. What is the benefit of CQRS when compared to a typical DDD architecture that uses Event Sourcing and properly captures intent and behavior via verb-based commands? (other than Scalability)

2. When using CQRS what do you do with complex query-based logic?

I’m going to elaborate on #1 in this blog post and I’ll do a follow-up post on #2.

I watched through Greg Young’s video on the business benefits of CQRS + Event Sourcing and first let me say that I thought it was an excellent presentation that really drives home a lot of the benefits to this approach to architecture (I watched it twice in a row I enjoyed it so much!). But it didn’t answer some of my questions fully (I wish I had been there to ask these of Greg in person!). So let me pick apart some of the points he makes and how they relate to my first question above.

  • I’m completely sold on the idea of event sourcing and have a clear understanding of the benefits that it brings to the table, so I’m not going to question that. But you can use event sourcing without going to a CQRS architecture, so my main question is around the benefits of CQRS + Event Sourcing vs Event Sourcing + Typical DDD architecture

Architectures Compared

Architecture with Event Sourcing + Commands on Left, CQRS on Right

  • Greg talks about how the stereotypical architecture doesn’t support DDD, but is that only because his diagram shows DTO’s coming up from the client. If we use the same diagram but allow the client to send commands doesn’t that remove a lot of the arguments that Greg makes against the stereotypical architecture?
    • We can now introduce verbs into the system.
    • We can capture intent now (storing it still requires event sourcing, but you can implement event sourcing without doing CQRS)
    • We can create a rich domain model (as opposed to an anemic domain model)
  • Scalability is obviously a benefit that CQRS brings to the table, but like Greg says, very few of the systems we create truly need significant scalability

  • Greg talks about the ability to scale your development efforts. He says CQRS allows you to split the system into 3 parts (Client, Domain/Commands, Reads) and assign 3 teams of developers to work on them in parallel; letting you scale your development efforts by 3x with nearly linear gains. But in the stereotypical architecture don’t you already have 2 separate modules that you can split your dev efforts between: The client that sends commands/queries and receives DTO’s, and the Domain which accepts commands/queries, and generates events/DTO’s. If this is true it’s not really a 3x scaling you achieve with CQRS but merely a 1.5x scaling which while great doesn’t sound nearly as dramatic (“I can do it with 10 devs in 12 months – let me hire 5 more and we can have it done in 8 months”).

  • Making the Query side “stupid simple” such that you can assign junior developers (or even outsource it) sounds like a valid benefit, but I have some concerns over what you do with complex query-based logic/behavior. I’m going to go into more detail on this in a follow-up blog post shortly. He also seemed to focus on how “stupid-simple” it is doing queries against the de-normalized data store, but I imagine there is still significant complexity in the event handlers that interpret the events and apply them to the de-normalized tables.

  • It sounds like Greg suggests that because we’re doing CQRS that allows us to apply Event Sourcing when we otherwise wouldn’t be able to (~33:30 in the video). I don’t believe this is true. I don’t see why you wouldn’t be able to apply Event Sourcing without separating out the Commands and Queries. The queries would just operate against the domain model instead of the database. But you’d still get the benefits of Event Sourcing. Without CQRS the queries would only be able to operate against the current state rather than the event history, but even in CQRS the domain behaviors can only operate against the current state and I don’t see that being a big limiting factor. If some query needs to operate against something that is not captured by the current state you would just have to update the domain model to capture that information (no different than if that statement were made about a Command under CQRS).

Some of the benefits I do see being applicable are that your domain model might end up being simpler/smaller since it only needs to represent the state needed to process commands and not worry about the reads (like the Deactivate Inventory Item and associated comment example that Greg provides). And also commands that can be handled in a Transaction Script style manner by the command handler simply generating events and not touching the domain model. It also makes it easier for your senior developers to focus on the command behavior and ignore the queries, which is usually going to be a better use of their time. And of course scalability.

If anybody out there has any thoughts on this and can help educate me further, please either leave a comment or feel free to get in touch with me via email: Email

Posted on Tuesday, June 8, 2010 2:40 PM | Back to top


Comments on this post: CQRS – Questions and Concerns

# re: CQRS – Questions and Concerns
Requesting Gravatar...
Hi,

it seems that you're not doing Event Sourcing but have just enabled Commands on your domain using a Task Based UI.

Event Sourcing is not only sending commands, but especially Emitting Events in response of this commands, and at is core, storing this Events as the primary domain persitance mechanism.
To reload the domain, you load the events and replay them (becareful, you replay Events, *not* Commands).

In this case, CQRS is quite not optional since the domain is not queriable anymore. You build a queryable copy of the domain fed by the Events.

The gain is truly in the business value of the Event Log. Any change in your system has been recorded with Domain semantic. It is very valuable. You loose nothing (yes nothing) from what happened in your system.

There should be no complexity in the event handlers that denormalize the events since any decision has been taken in the domain.

The is a really better independance between the 3 parts :
Client devs only focus on making commands from query dtos,
Domain devs only focus on emitting events from commands (no persistance concern)
ReadDb devs only focus on putting data from events on efficient data structures for query.

Left by thinkbeforecoding on Jun 08, 2010 3:29 PM

# re: CQRS – Questions and Concerns
Requesting Gravatar...
To address your comments, in my picture on the left the idea is it is not only processing commands but emitting events, and storing those events in the event store (as per Event Sourcing).

I'm not sure why you say you can't do event sourcing without CQRS. Event sourcing has been in use long before CQRS was thought up. Fowler was writing about it 5 years ago (http://martinfowler.com/eaaDev/EventSourcing.html).

My understanding is that if you use event sourcing without CQRS you execute your queries against your domain model. Essentially meaning your domain model is responsible for processing commands and emitting events *and* processing queries and emitting either domain objects which the application services layer maps to DTO's, or having the domain model directly emit the DTO's.

When you say "there should be no complexity in the event handlers that denormalize the events" I don't see how that is true. You’re going to have a denormalized table that will need to be updated when (for example) 12 out of the 200 possible events available are fired. Figuring out which 12 events are applicable to that table, and what changes need to be made to that table when one of those events is fired sounds like complexity to me. Multiply that by the 100's of denormalized tables a mid-sized app probably needs, and it adds up to not only alot of tedious work, but alot of complex work in figuring out which events map to which tables that requires domain knowledge of the person doing that design.

As for the independence between the 3 parts I understand the idea, but even without CQRS you still have just as much independence between the client and the "non-client" IMHO. It just means there's no separation between "domain devs" and "ReadDb devs" without CQRS.

I hope I'm not coming off as sounding confrontational or negative towards CQRS. In my gut it feels like a great way to architect a system, I'm just having trouble trying to conceptualize the actual benefits of the approach so that I can communicate them effectively to the rest of my teams and management.
Left by Dylan Smith on Jun 08, 2010 4:46 PM

# re: CQRS – Questions and Concerns
Requesting Gravatar...
Hey, no problem with criticisms, it's rather constructive to give better answers,

I understand how you integrate Event Sourcing without CQRS (btw be careful with Martin Fowler's definition, it has been reconized has containing serious flaws...)

The problem with serving queries from the object model is that is requiers your model to be designed for transactionality (commands) and for efficient queries (queries).
Queries usually span over several Aggregate Roots :
- in case of lists, AR of the same type, but with query concerns as filtering, sorting and paging
- in case of traversal, AR of different types (Customer.Orders ..). It can even span on several Bounded Contexts

The problem here is that your repositories will have to manage paging etc, your Aggregate Root and Entities will have to manage traversal (but should you load traversal properties when applying a command ?, should you use lazy load, and the prefetch paths for performance etc...)
Even if your whole domain is in memory, you have to maintain these traversal properties that will bloat the domain.

Of course the event handlers that denormalize to views should be treated carefully so that views stay in synch with the domain, but it is not critical since the views can be rebuild from scratch if a problem occures.
When I say 'no complexity' it's that you should only have a simple Insert/Update/Delete statement in each handler, you should have no decision to take.

Left by thinkbeforecoding on Jun 09, 2010 3:52 AM

# re: CQRS – Questions and Concerns
Requesting Gravatar...
Jeremie brings up some obvious issues with using event sourcing and querying off the object model but there are others.

How would you handle a pivot or an aggregation query? eg: I would like to see the total of sales per customer. With event sourcing this quickly becomes highly inefficient. Keeping the separate model allows us to keep the data in a way that makes querying easy.

The real focus of CQRS is to avoid having to make one size fits all decisions. We could do queries off our domain model with or without event sourcing but it is a far from optimal method. We can end up in a much better place by allowing ourselves to make different decisions on the two sides. At first this may seem like complexity but it actually simplifies the overall process.

For complex logic, these things should be denormalized onto the events. A canonical example would be sales tax. There are however some cases where this can not be done, generally these are BI situations where you are running "what if scenarios" and you are forced to re-run calculations. It is important to remember that these are not the norm.

Cheers,

Greg
Left by Greg Young on Jun 09, 2010 5:32 AM

# re: CQRS – Questions and Concerns
Requesting Gravatar...
I was waiting for the next post to make this remark greg :-P

To continue on the subject, I often hear 'but we have queries that require domain logic'...
In our system, we have to return plannings etc...
Sometimes you just have to build special Query mechanism that you won't find out of the box. We had to build a planning database for our need. But this is not domain logic, this is just structuring data for query need, with a 'query language' that is not SQL.
But you'll already find this with an Olap Cube that is not SQL or a document db...
Left by thinkbeforecoding on Jun 10, 2010 3:40 AM

# re: CQRS – Questions and Concerns
Requesting Gravatar...
Sometimes you do end up with logic on the query side.

As an example, what would happen if we changed our sales tax calculation to XYZ. Almost always these cases are like this (what would happen if...) (what if we made the ABC trading strategy trade only when RSI is > 0 and all of its other things are true, would it be more or less efficient?). But they do exist, there is just no good way of dealing with them through the domain nor is it really duplication as they are handling a very different scenario.
Left by Greg Young on Jun 10, 2010 4:14 AM

# re: CQRS – Questions and Concerns
Requesting Gravatar...
Hi Greg - what if the only intelligent thing that our system does is just running these what if scenarios (queries), and all other objects in our model are merely configuration data to be used in the execution of these scenarios, which return some execution result to the user, - what's the best way of dealing with this?
Left by KaanK on Jan 16, 2011 8:45 PM

# re: CQRS – Questions and Concerns
Requesting Gravatar...
Kaank,
I'd have to know more about the domain to give proper advice, but it sounds like the command side of your domain is merely a handful of screens over data with little business logic.

If true, I'd probably favor something like an Active Record pattern to handle my data updates, then a typical data warehouse type approach to de-normalize to optimize the high-value queries that you you need to run (the what-if scenarios).
Left by Dylan Smith on Mar 14, 2011 11:26 PM

Your comment:
 (will show your gravatar)


Copyright © Dylan Smith | Powered by: GeeksWithBlogs.net