views:

145

answers:

2

Can you use the CQRS (Command-Query Responsibility Segregation) architectural pattern to build a site like StackOverflow? I'm relatively new to CQRS and DDD (Domain Driven Design) and am exploring the pattern and trying to model sites that I'm familiar with to the pattern. While I can see CQRS being useful for many aspects for a site like StackOverflow, there are a few areas that I'm not sure are possible (or, at least, I can't figure out immediately). Specifically:

  • Asking questions When I create a question, I see it immediately and can edit it. In CQRS, I issue a command like 'AskQuestion' and an event is created called 'QuestionAsked'. Eventually, the question gets pushed to the denormalized data store. But SO's experience is immediate. Is this possible with CQRS?
  • Voting My votes are reflected immediately. In CQRS, I would imagine these commands/events eventually moving through the event bus to the read store. But SO gives me the information immediately.

My concerns are really around the concept of immediate feedback that SO provides. Can CQRS provide this? If so, how would this be done? Are there good examples out there that illustrate how to handle this?

If it helps, my environment is VS2010/C#/SQL2008R2, but I'm open to other options like SQLite, etc. I'm also looking at NCQRS and LOKAD's frameworks, along with Mark Nijhof's sample and am planning on downloading Greg Young's sample. I didn't find much else out there for CQRS samples.

Thanks!

+3  A: 

When you ask a question, you can "fake" the data in the UI. It will look like it was updated immediately to the user (you), but it will take some time before the other users will see your question. You need to do the same thing to handle voting.

If you need immediate feedback, you might consider other solutions. But, there are some tricks you can do to give immediate feedback in a CQRS solution. If you, for example, need to validate that a username is uniqe, you can query the read database(s) to find out if the username exists. If it doesn't, you can use it. But, if a other user have choosen the same username in the meantime, you will get a conflict on the command side. You need to handle this in your domain model, and, for example, give the user a generated username and send it to him by e-mail. He can later change it to something else.

Fossmo
"fake" and "trick" are not very reassuring... this looks more like a hack, a workaround rather than a sound solution.
Mauricio Scheffer
By fake I mean that you don't have to send data back to the database/server before you go to a screen where data is needed. There is not a problem to wait until the data has been through the system (writeside and readside), but you have to train the user to refresh the screen or set up some kind of pulling mechanism. This can impact the user experience. And, it's not a hack to be smart ;-)
Fossmo
Be reassured, Fake is exactly what you need! It's a bit of a mind shift...
gkdm
+1  A: 

What you're actually talking about is 'eventual consistency' which is frequently talked about at the same time as CQRS, but you can use either technique independently.

The simplest thing to do is to update the model which the UI is using immediately and use this to show the question back to the user for further manipulation. The various bits of work to be done so that the other users can see the update can then proceed without blocking the UI. For this to work you need to validate your command so that is almost certain to succeed before sending it off (if the command fails during execution then you'll need to handle the situation, e.g. incorporate some sort of call back to the UI model).

It's also worth bearing in mind that usually the 'eventuallness' of this sort of thing is so quick that everything will have appeared immediately anyway, even to other users.

FinnNk