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:
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!
When to use CQRS pattern. Consider CQRS for the following scenarios: Collaborative domains where many users access the same data in parallel. CQRS allows you to define commands with enough granularity to minimize merge conflicts at the domain level, and conflicts that do arise can be merged by the command.
The use of CQRS as part of a system should not belong to its strategic design. It should only be used in the design of some of the components and not become the base of the entire system. If the system is complex enough, using CQRS as the basis for everything may become too complex and some advantages may be lost.
CQRS is implemented by a separation of responsibilities between commands and queries, and event sourcing is implemented by using the sequence of events to track changes in data.
If you're applying CQRS and Vertical Slice Architecture you'll likely want a repository to build up Aggregates. However, for a Query, you may want to just get the data you need rather than an entire aggregate (or collection of aggregates) to build a view model.
The short answer is: Yes, you can. CQRS as an architectural style came after DDD. It's based on the Command-Query Separation (CQS). As a pattern CQRS can be used to optimize your application.
CQRS is a popular architecture pattern because it addresses a common problem to most enterprise applications. Separating write behavior from read behavior, which the essence of the CQRS architectural pattern, provides stability and scalability to enterprise applications while also improving overall performance.
Let's look at the two questions...
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?
This can be easily achieved. Does every user need to see the question immediately or just the person asking it? If it takes 1-2 seconds for it to appear to everyone would it make a difference? Most often in eventually consistent systems there is a difference between the user sending a request vs every other user.
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.
Does SO give it immediately? Let's try another example, Facebook. When you click like on something does this immediately show up in your likes? UI tricks like putting a thumbs up make you feel like it does. Another example, amazon. When you click add to cart does it immediately go into your cart? Visual representations like "added to cart" or a "thumbs up" make you as a user feel like its been done.
There are many tricks like these that can make an eventually consistent system feel like a fully consistent system.
As a side note many people think these kinds of thing are done for scalability (which is sometimes the case). More often they are being done for reliability. The question becomes happens if XYZ is down. Do you want weird randomized local failures or do you want to risk a wide spread outage. One of the best examples to see here is checking out on amazon for a kindle purchase, its weird that they can process your credit card in like 100ms while everyone else takes 3-5 seconds :) What happens if their credit card processing system is down?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With