It is true when you think about it. In almost all languages the concept of CQRS has been kind of merged into Command Bus/Pipeline concept. So when you mention CQRS people are automatically like :Oh, you mean command gateway, command handlers, MediatR...
I'd agree that in the .NET space, most would assume MediatR when you mention CQRS. MediatR doesn't imply you're doing CQRS either however. CQRS is simply an extension of CQS (from Bertrand Meyer). Methods are commands if they perform action or a query if they return data, not both. Greg took it a step further and said "CQRS is simply the creation of two objects where there was previously only one." It has nothing to do with data models (persistence) as this video suggestions. The "two" objects Greg is referring to is at the service layer. Does it mutate state or return state. This could be a class with 10 methods that all return state (queries) or mutate state (commands), but not mixing both. If you narrow this down to a single method, you'll land on up with the command pattern. Take it further you'll end up with creating a pipeline.
Official Microsoft docs pretty much suggests different data models straight away. - docs.microsoft.com/en-us/azure/architecture/patterns/cqrs#solution Martin talks about separate object models and suggests potentially different data models. - martinfowler.com/bliki/CQRS.html > By separate models we most commonly mean different object models > There's room for considerable variation here. The in-memory models may share the same database, in which case the database acts as the communication between the two models. However they may also use separate databases, effectively making the query-side's database into a real-time ReportingDatabase. In this case there needs to be some communication mechanism between the two models or their databases. Uri talks about benefits of CQRS from a building multi user collaborative software. The 1st thing he does is defines a separate data model for queries, and rather focuses on making sure the commands are valid while working with stale data. - udidahan.com/wp-content/uploads/Clarified_CQRS.pdf The 1st summary Greg makes is giving commands and queries different data models. He goes on to highlight data mapping as one of the big pain points. He does not state that you have to have a separate data model in the Query section, but definitely advocates for bypassing the domain object model. He does question having identical data models. - cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf > Command: The Command side being a transaction processor in a relational structure would want to store data in a normalized way, probably near 3rd Normal Form (3NF) > Query: The Query side would want data in a denormalized way to minimize the number of joins needed to get a given set of data. In a relational structure likely in 1st Normal Form (1NF) > By applying CQRS the concepts of Reads and Writes have been separated. It really begs the question of whether the two should exist reading the same data model or perhaps they can be treated as if they were two integrated systems I do not disagree, per-se but saying "It has nothing to do with data models (persistence) as this video suggestions." is not right, it's more of YAGNI and using your own professional discretion is advised.
I ended up writing my own libraries for facilitating CQRS based on Steven Van Deursen's articles "Meanwhile... on the command side of my architecture" and "Meanwhile... on the query side of my architecture" combining some architecture based on an open source project called Tripod, kind of glad I never had the need to join the masses with MediatR. I think sometimes it's good to go through the proces of building core frameworks yourself to really understand what is going on.
As always your explanation is awesome and helped me a lot to understand the topic. Thanks!! But I have a few queries. Can you please answer them? 1) Is Materialized View as separate Read Database a good option than somewhat complex Event Sourcing? 2) At 2:40 your Process is projecting into View Store directly from Command rather than from Command Side Database Projection. Then what is the use of Command side Database in such case (In fact it is never used)? 3) At 8:52 when you need to query/load data at Command side, you read data from ViewStore(Read Db). Wouldn't it be better that in such cases, for e.g. business validations before saving, where we first need to query data at Command side , we use Commnand Db for query to avoid momentary stale data because of eventual consistency issue?
I have the same question at point 2. Process must be fire and forget task. So it's impossible to take query instantly for the fact that don't we have any "triger" that tell us that viewmodel store was updated. So I think that this is the principal point of the cqrs problem . Mainly scenarios that comes from web views that insert or edit some kind of data and the user should view this data faster as possible. Or maybe cqrs should don't be used in this scenarios and should be used in other types.?
In an Enterprise large scale solution, would you use a layer for the event sourcing such as Service Bus / Message Queuing? Given large scale loads if there's any system outages, those technologies can ensure data will actually reach the View Store. On our platform in my day job we had a "event_message" database table were we publish minimal information for an event to find the data to be synced rather than putting an entire record. Then a Service Bus publisher reads batches of records from there and is responsible for creating the Service Bus Topics on the queue. A Subsriber then reads those and farms topics off to Handlers which know how to query for relevent data. In your scenario here, that handler would query the main data store and then update the View Store, the big benefit being that these handlers run off process from the main Command layers and you can pool handlers to load balance on high traffic. It may seem like a lot of moving parts but I can imagine in huge scale systems that the time in process to update the View Store could potentially hold up the Commands and in reality what's the point fo "eventual consistency" if you're going to udpate the store immediately and hodld the command up anyway... With some kind of message queue as I outlined only a tiny bit of info needs to be in the "Event" and then the command can return immediately meaning more room to process incoming commands. If anything along the way dies then you have the Event published record so you could re-run the pushes. This could be either re-running the publish if that failed, or the Subscriber doesn't remove from the queue until the View Store update is finalised, so that could also be re-run the View Store update at ay time. One key part of all this is that each command would have a unique "correlationId" which appears on the message queue and then logs of each command are kept with that same value so you can still link all the actions together when debugging.
In a real case scenario where you are actually querying a real database vs an in memorydatabase I think you would have seen more differences. We prefere the cached scenario you talked about in the end, just clearing the cached version in a mediatR pipeline. So the "process" will only be fire on the next read, and not on every writes.
Great video regarding a very ambiguous topic :) One question that I have is how to do you handle de-sync in a non-eventsourced system? Asking for the case where we fail to build/update the query model (db down or any other transient issue). Furthermore, if business requirements change for the viewmodel, how would you reconstruct the data?
You have to assume vm is valid regardless if it’s stale or not and validate the commands instead. With regards to having multiple vms or changing them you’ll just have to create mapping functions
Love to hear that there is somebody else that is not a MediatR fanatic. So I have had endless arguments over what is CQRS. I think the separation of DBs is clearly CQRS, but what's your opinion on: 1. having different C# models going to the same db. eg a POST which has the full model, a PATCH that has a partial model, then different reads that have different projections of the data. So different C# models which interact with the same set of data. 2. What if the read method and write method are in the same class but have different models and different databases. Would you consider those CQRS, putting other design aside?
It’s hard to answer your question because you don’t specify which models - object or data. Post/patch/delete don’t matter we execute commands if they are valid - commands interact with the domain/object model and then get save to the main data model (no duplicate data) It’s okey to have the same class to execute query and commands, even on the same data models (not object models) as long as their query and command paths are separated by interfaces.
I don't understand how it can be useful for one to many or many to many relationship. I can see the benefit if you have 4 foreign keys with a one to one relationship. In a database you can just create a big table so you don't have to do joins, but with a one to many relationship you have to do them otherwise you could have a billion rows.
Hi Raw Coding, I am from Ukraine and I always watch your videos, currently, I see war behind the window, please assist us, let the entire world know about the situation in Ukraine. Everyday Russian kill us. But we are brave and stay here, for one purpose - defend our families and country. Glory to Ukraine. Thanks for your attention
They are. Check Instagram every Russian is talking about it, panic buying, taking all money out of banks, deleting their vk accounts etc... Everyone is talking about it. If someone is not aware of this war they don’t have access to the internet.
It is true when you think about it. In almost all languages the concept of CQRS has been kind of merged into Command Bus/Pipeline concept. So when you mention CQRS people are automatically like :Oh, you mean command gateway, command handlers, MediatR...
I'd agree that in the .NET space, most would assume MediatR when you mention CQRS. MediatR doesn't imply you're doing CQRS either however. CQRS is simply an extension of CQS (from Bertrand Meyer). Methods are commands if they perform action or a query if they return data, not both. Greg took it a step further and said "CQRS is simply the creation of two objects where there was previously only one." It has nothing to do with data models (persistence) as this video suggestions. The "two" objects Greg is referring to is at the service layer. Does it mutate state or return state. This could be a class with 10 methods that all return state (queries) or mutate state (commands), but not mixing both. If you narrow this down to a single method, you'll land on up with the command pattern. Take it further you'll end up with creating a pipeline.
Official Microsoft docs pretty much suggests different data models straight away.
- docs.microsoft.com/en-us/azure/architecture/patterns/cqrs#solution
Martin talks about separate object models and suggests potentially different data models.
- martinfowler.com/bliki/CQRS.html
> By separate models we most commonly mean different object models
> There's room for considerable variation here. The in-memory models may share the same database, in which case the database acts as the communication between the two models. However they may also use separate databases, effectively making the query-side's database into a real-time ReportingDatabase. In this case there needs to be some communication mechanism between the two models or their databases.
Uri talks about benefits of CQRS from a building multi user collaborative software. The 1st thing he does is defines a separate data model for queries, and rather focuses on making sure the commands are valid while working with stale data.
- udidahan.com/wp-content/uploads/Clarified_CQRS.pdf
The 1st summary Greg makes is giving commands and queries different data models. He goes on to highlight data mapping as one of the big pain points. He does not state that you have to have a separate data model in the Query section, but definitely advocates for bypassing the domain object model. He does question having identical data models.
- cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf
> Command: The Command side being a transaction processor in a relational structure would want to
store data in a normalized way, probably near 3rd Normal Form (3NF)
> Query: The Query side would want data in a denormalized way to minimize the number of joins needed
to get a given set of data. In a relational structure likely in 1st Normal Form (1NF)
> By applying CQRS the concepts of Reads and Writes have been separated. It really begs the question of
whether the two should exist reading the same data model or perhaps they can be treated as if they
were two integrated systems
I do not disagree, per-se but saying "It has nothing to do with data models (persistence) as this video suggestions." is not right, it's more of YAGNI and using your own professional discretion is advised.
I ended up writing my own libraries for facilitating CQRS based on Steven Van Deursen's articles "Meanwhile... on the command side of my architecture" and "Meanwhile... on the query side of my architecture" combining some architecture based on an open source project called Tripod, kind of glad I never had the need to join the masses with MediatR. I think sometimes it's good to go through the proces of building core frameworks yourself to really understand what is going on.
@@RawCoding I wrote a lengthy reply but it was marked as spam? Oh well.
TH-cam does that sometimes, I can’t find anything in history or held for review. If you still have a copy send me it I’ll reply on your behalf
It's nice to see how this channel is growing! Great content as usual, cheers!
Thank you 🙏
Nice! A short video that highlights the main point.
As always your explanation is awesome and helped me a lot to understand the topic. Thanks!!
But I have a few queries. Can you please answer them?
1) Is Materialized View as separate Read Database a good option than somewhat complex Event Sourcing?
2) At 2:40 your Process is projecting into View Store directly from Command rather than from Command Side Database Projection. Then what is the use of Command side Database in such case (In fact it is never used)?
3) At 8:52 when you need to query/load data at Command side, you read data from ViewStore(Read Db). Wouldn't it be better that in such cases, for e.g. business validations before saving, where we first need to query data at Command side , we use Commnand Db for query to avoid momentary stale data because of eventual consistency issue?
I have the same question at point 2. Process must be fire and forget task. So it's impossible to take query instantly for the fact that don't we have any "triger" that tell us that viewmodel store was updated. So I think that this is the principal point of the cqrs problem . Mainly scenarios that comes from web views that insert or edit some kind of data and the user should view this data faster as possible. Or maybe cqrs should don't be used in this scenarios and should be used in other types.?
In an Enterprise large scale solution, would you use a layer for the event sourcing such as Service Bus / Message Queuing? Given large scale loads if there's any system outages, those technologies can ensure data will actually reach the View Store. On our platform in my day job we had a "event_message" database table were we publish minimal information for an event to find the data to be synced rather than putting an entire record. Then a Service Bus publisher reads batches of records from there and is responsible for creating the Service Bus Topics on the queue. A Subsriber then reads those and farms topics off to Handlers which know how to query for relevent data. In your scenario here, that handler would query the main data store and then update the View Store, the big benefit being that these handlers run off process from the main Command layers and you can pool handlers to load balance on high traffic. It may seem like a lot of moving parts but I can imagine in huge scale systems that the time in process to update the View Store could potentially hold up the Commands and in reality what's the point fo "eventual consistency" if you're going to udpate the store immediately and hodld the command up anyway... With some kind of message queue as I outlined only a tiny bit of info needs to be in the "Event" and then the command can return immediately meaning more room to process incoming commands. If anything along the way dies then you have the Event published record so you could re-run the pushes. This could be either re-running the publish if that failed, or the Subscriber doesn't remove from the queue until the View Store update is finalised, so that could also be re-run the View Store update at ay time. One key part of all this is that each command would have a unique "correlationId" which appears on the message queue and then logs of each command are kept with that same value so you can still link all the actions together when debugging.
Great explanation as always dude!
In a real case scenario where you are actually querying a real database vs an in memorydatabase I think you would have seen more differences. We prefere the cached scenario you talked about in the end, just clearing the cached version in a mediatR pipeline. So the "process" will only be fire on the next read, and not on every writes.
Great video regarding a very ambiguous topic :) One question that I have is how to do you handle de-sync in a non-eventsourced system? Asking for the case where we fail to build/update the query model (db down or any other transient issue). Furthermore, if business requirements change for the viewmodel, how would you reconstruct the data?
You have to assume vm is valid regardless if it’s stale or not and validate the commands instead. With regards to having multiple vms or changing them you’ll just have to create mapping functions
Great Explanation Sir
You're on fire man hahaha nice video
as usual i learn something from your videos, can you make a graphql asp.net core series? or is there any plan for that?
This lesson was good!
Love to hear that there is somebody else that is not a MediatR fanatic. So I have had endless arguments over what is CQRS. I think the separation of DBs is clearly CQRS, but what's your opinion on:
1. having different C# models going to the same db. eg a POST which has the full model, a PATCH that has a partial model, then different reads that have different projections of the data. So different C# models which interact with the same set of data.
2. What if the read method and write method are in the same class but have different models and different databases.
Would you consider those CQRS, putting other design aside?
It’s hard to answer your question because you don’t specify which models - object or data.
Post/patch/delete don’t matter we execute commands if they are valid - commands interact with the domain/object model and then get save to the main data model (no duplicate data)
It’s okey to have the same class to execute query and commands, even on the same data models (not object models) as long as their query and command paths are separated by interfaces.
I don't understand how it can be useful for one to many or many to many relationship. I can see the benefit if you have 4 foreign keys with a one to one relationship. In a database you can just create a big table so you don't have to do joins, but with a one to many relationship you have to do them otherwise you could have a billion rows.
Sorry I’m not sure what you mean, we store in document/kv storage
@@RawCoding Thanks for the reply, I just haven't worked with NoSQL before so I was a bit confused
Just a suggestion, don’t use dark red on a dark grey background, it’s very hard to make out what you are drawing.
Nice, that you focus on the actual pattern and skip mediator....
Please normalize your audio. Your content is too good not to :P.
Usually it fucks it up even more when I do it, I just got to stop mumbling
Hi Raw Coding, I am from Ukraine and I always watch your videos, currently, I see war behind the window, please assist us, let the entire world know about the situation in Ukraine. Everyday Russian kill us. But we are brave and stay here, for one purpose - defend our families and country.
Glory to Ukraine. Thanks for your attention
What help would you like?
@@RawCoding share this information about the situation in Ukraine with your friends and subscribers, thank you for answer
You think someone is still not aware of the war? What would that achieve?
@@RawCoding russians don't know about this war
They are. Check Instagram every Russian is talking about it, panic buying, taking all money out of banks, deleting their vk accounts etc... Everyone is talking about it. If someone is not aware of this war they don’t have access to the internet.