CQRS – Is It Overengineering?

asp.netasp.net-mvc-web-apicqrsnetweb-api

I still remember good old days of repositories. But repositories used to grow ugly with time. Then CQRS got mainstream. They were nice, they were a breath of fresh air. But recently I've been asking myself again and again why don't I keep the logic right in a Controller's Action method (especially in Web Api where action is some kind of command/query handler in itself).

Previously I had a clear answer for that: I do it for testing as it's hard to test Controller with all those unmockable singletons and overall ugly ASP.NET infrastructure. But times have changed and ASP.NET infrastructure classes are much more unit tests friendly nowadays (especially in ASP.NET Core).

Here's a typical WebApi call: command is added and SignalR clients are notified about it:

public void AddClient(string clientName)
{
    using (var dataContext = new DataContext())
    {
        var client = new Client() { Name = clientName };

        dataContext.Clients.Add(client);

        dataContext.SaveChanges();

        GlobalHost.ConnectionManager.GetHubContext<ClientsHub>().ClientWasAdded(client);
    }
}

I can easily unit test/mock it. More over, thanks to OWIN I can setup local WebApi and SignalR servers and make an integration test (and pretty fast by the way).

Recently I felt less and less motivation to create cumbersome Commands/Queries handlers and I tend to keep code in Web Api actions. I make an exception only if logic is repeated or it's really complicated and I want to isolate it. But I'm not sure if I'm doing the right thing here.

What is the most reasonable approach for managing logic in a typical modern ASP.NET application? When is it reasonable to move your code to Commands and Queries handlers? Are there any better patterns?

Update. I found this article about DDD-lite approach. So it seems like my approach of moving complicated parts of code to commands/queries handlers could be called CQRS-lite.

Best Answer

Is CQRS a relatively complicated and costly pattern ? Yes.

Is it over-engineering ? Absolutely not.

In the original article where Martin Fowler talks about CQRS you can see a lot of warnings about not using CQRS where it's not applicable:

Like any pattern, CQRS is useful in some places, but not in others.

CQRS is a significant mental leap for all concerned, so shouldn't be tackled unless the benefit is worth the jump.

While I have come across successful uses of CQRS, so far the majority of cases I've run into have not been so good...

Despite these benefits, you should be very cautious about using CQRS.

...adding CQRS to such a system can add significant complexity.

My emphasis above.

If your application is using CQRS for everything, than it's not CQRS that's over-engineered, it's your application. This is an excellent pattern to solve some specific problems, especially high performance/high volume applications where write concurrency may be a major concern.

And it may not be the entire application, but only a small part of it.

A live example from my work, we employ CQRS in the Order Entry system, where we cannot lose any orders, and we do have spikes where thousands of orders come at the same time from different sources, in some specific hours. CQRS helped us to keep the system alive and responsive, while allowing us to scale well the backend systems to process these orders faster when needed (more backend servers) and slower/cheaper when not needed.

CQRS is perfect for the problem where you have several actors collaborating in the same set of data or writing to the same resource.

Other than that, spreading a pattern made to solve a single problem to all your problems will just create more problems to you.


Some other useful links:

http://udidahan.com/2011/04/22/when-to-avoid-cqrs/

http://codebetter.com/gregyoung/2012/09/09/cqrs-is-not-an-architecture-2/