13

I'm thinking about applying CQS for my ASP.NET MVC web site, but in a very simple matter. I don't mean CQRS, because I want to use the same data source for query and command parts, and so I don't need event sourcing and other more complex patterns.

So, what I have in mind is:

  • use the same database for query and command part
  • for the query part, expose database views with entity framework and WCF data services, so that specific views are returned to the client, querying data becomes very easy
  • for the command part, expose database tables with entity framework and one-way WCF services, and using DDD principles.

The main thing I want to achieve is:

  • simple commands that are executed by one-way service operations, and handled by a rich domain model, client needs to pass only the data that is really needed to perform the command
  • flexible querying on simple views, designed for the specific UI of the client

Does this make sense?

casperOne
  • 73,706
  • 19
  • 184
  • 253
L-Four
  • 13,345
  • 9
  • 65
  • 109
  • It makes sense to me. You do not need the distribution model and bus architecture of a full CQRS system for small-to-medium scale systems. – Deleted Aug 02 '11 at 20:02
  • Thanks, and I guess that if I ever would need the full system for certain parts, it would be possible to do so because my interfaces are already separated... – L-Four Aug 03 '11 at 07:27
  • 1
    yep spot on. I think that it's probably better to evolve the system into separate concerns first (scale out), then use CQRS as a last resort myself. – Deleted Aug 03 '11 at 10:06
  • How do you handle errors in the commands ? I am facing the same setup as you (WPF instead of ASP .NET), but I am not sure what to do - should I always 'assume' the command has succeeded ? what if it hasn't ? – John Miner May 12 '12 at 14:55
  • My commands can throw exceptions, which are handled by a global exception handler. – L-Four May 06 '15 at 13:55

1 Answers1

9

So, to answer your question, yes I think it makes sense.

I'm not sure what else you're looking for. I think the approach you're taking makes sense and should give you what you are looking to do.

In my opinion, CQS and CQRS are very similar, where CQRS has the concept of separate read and write stores (and some would argue that the write store may not even be necessary). Event sourcing isn't really part of CQRS - it's an add-on, so to speak, that fits in nicely with the distributed nature of CQRS.

What you're giving up with your approach is some of the scalability of the data since you're flattening the data using views. But if your app doesn't require it, then there's no problem there.

Also, it may be useful to read Udi Dahan's article on when to avoid CQRS. It probably helps justify your decisions. It caused quite a stir when he released it. But between him and Greg Young, they're the experts on CQRS.

I'm not sure if I answered your question or helped, but good luck with your project! I hope this helps.

David Hoerster
  • 28,421
  • 8
  • 67
  • 102
  • Thank you, indeed, I also read that post. I guess he is saying that you rarely need full blown CQRS, or even any layering. I agree partly here, that's the reason I want to apply only lightweight CQS. But the pattern to split query from command make things simpler, I think, but because it's a big design decision, I want to be sure it's a valid approach. The only thing I'm not sure about now, is whether to use a Guid as key in DB, because the command pattern needs that and I worry about performance. Thanks for the comments! – L-Four Aug 03 '11 at 04:56
  • The command side doesn't need a guid...but that's just the common way to get a client side unique id. Usually it's preferred to get the id before issuing the command...a guid is just convenient. You can use an int or anything else. It's up to you. :). Hope this helps! – David Hoerster Aug 03 '11 at 09:54
  • "Guid as key in DB, because the command pattern needs that and I worry about performance" - You could use a sequential GUID that wouldn't have that much impact on the performance instead of an INT/BIGINT. (http://stackoverflow.com/questions/170346/what-are-the-performance-improvement-of-sequential-guid-over-standard-guid) – Magnus Gladh Aug 03 '11 at 10:52
  • @David: I find your statement 'Usually it's preferred to get the id before issuing the command' interesting... can you elaborate a bit on that? – L-Four Aug 03 '11 at 17:58
  • Here's a good discussion on the DDD/CQRS google group around that. http://groups.google.com/group/dddcqrs/browse_thread/thread/04dd29d122acd4e0/a285384bdcc4c884#a285384bdcc4c884 . Udi Dahan (2nd comment in the thread) is where I'm coming from. I prefer to generate my IDs and pass them in with my command. This way, my client knows what ID was generated. – David Hoerster Aug 03 '11 at 18:01
  • @David: yes I certainly see the advantage and I would like to do the same... but I don't understand how this can be an int? – L-Four Aug 03 '11 at 19:28
  • @Lud: well, you could have a service that you call that returns to you a unique int (generated somehow -- from a db table, some other generator, etc.). Once you call that service to get your int, then you set it in your command and send it off to your command handler. I use a service that creates a GUID and tracks it, and it also gives me a incrementing Int64 to go along with it. It works out pretty well. – David Hoerster Aug 03 '11 at 20:04
  • 1
    @David: interesting idea, then there are two things that come to mind: 1. it's an extra call, doesn't this hurt performance? And: 2. what if multiple commands come in at the same time, how do you make sure you give them unique id's? – L-Four Aug 04 '11 at 05:18