I love both of these videos. Sometimes it's the really deep, technical discussions that have a huge impact on the way I think, and sometimes it's videos like this that simply offer a different want to think about building software that really change that way I approach things. Another really important idea that you've espoused is concept of "tradeoffs". Allowing myself to entertain ALL solutions (even those people on Twitter swear never to do) and "intentionally" choose what offers the best balance at the moment sounds simple, but can be really difficult when learning (and trying not to shoot yourself in the foot).
Ya I was aware I left that out. I plan on making a video explicitly talking about it with examples. But ultimately the tradeoff between option vs cost on laying the ground work for those options in the future.
CQRS is more as you describe here. It can be exactly what you are saying but I have found in context of manufacturing applications (This is what I learned over the last quarter of a century :) ) it can also mean and apply differently. In my effort what I have the last couple years, getting major monolith broken down in a SOA construct and in a construct where I do have a part of the software with high response requirements and a part where data needs to be available to many other services and business parts I see it this way: CQRS is a separation between C as "Command and Control" and Q as "Query in sense of reporting and analytics" ...therefor a want to keep the C part close to the production area. Probably OnPrem up to the edge at max. (all data that I need to produce or manufactore parts in seconds or minutes ...just in time (not realtime but ...almost :) ) and the Q part of data can be in different formats find there way in some kind of query optimized db, data lakes of whatever you call it. Available for everyone and everything decoupled from the real manufacturing process.
Just a thought on the CQRS portion of this video, have you had a look at Marten or similar library? Not always the 'right' choice It could act as a great demonstration of how simple event sourcing could be when you don't over complicate things.
This is all well and good. I like what your saying but I'm having a hard time putting that to a practical use of something I've interacted with in the past. If I were to rebuild that system, for example, could you show some examples?
I tend to use the term "systems architecture" when I'm on a system level (components, integrations, services etc), and "software architecture" when I'm at the software level (clean architecture, layers, SOLID etc). What's your opinion on this?
Ya, I can see that. I tend to avoid the term "distributed system" when talking about an application because I think most tend to view it in the sense of a distributed infrastructure, eg database.
I'm not convinced that using message passing instead of a function call automatically buys you "lower coupling". Maybe at best it's a form of "hidden coupling" since it's now harder to trace.
Passing messages via a durable message broker removes temporal coupling. Sender and Receiver don't need to be online/available at the same time. Publish/Subscribe patterns allows the publisher to be decoupled from the consumers. Publisher is totally unaware of who is subscribing or what they are doing with the event. Is it harder to visualize (or trace) calls between messages, it can be without distributed tracing.
In a monolith, using one database, if i start isolating/decoupling by module/bounded context (isolating repository interface to its corresponding module) would i lose entity relationship to some extent in the database and risk database integrity? Or should i share repository interface between modules so each can set its relationship to keep db integrity? Or should each module hide it's repo interface and expose only service interface for retrieving some entity for the other module that needs it? How important is database integrity in a modular monolith?
You can keep constraints with the knowledge that you know everything is on the same physical database. I don't actually run into this problem with integrity even without constraints
Depends. Often times they can delegate to domain objects or if not complex can be simply viewed as transaction scripts and work with data models and persistence.
@@CodeOpinion do I apply it correctly? the cqrs handler queries the db/repo to construct the domain models and call the methods/services (domain layer) and then saves the changes back to the db.
Of course not. It's a way to communicate between logical boundaries to prevent tight coupling. It gives you options for dealing with availability, failures, resilience, etc.
@@ruekkart Messaging is very versatile solution in general and applicable nearly everywhere. However it does bring complexity initially, especially if developers are unfamiliar with it (like Derek mentioned). Other options do exist but potentially are equally difficult in different areas. For example microservices resolve a lot of those issues if implemented correctly. Fault tolerance in this case, with services that rely on chain of calls with either HTTP or RPC is something to resolve separately, and there are more cases. I do agree with Derek that design of bounded context is very important either way, since communication between service is something that can be worked on, though it is better to decide on it from the start due to later complexity. TLDR: I don't think that any architecture in itself resolves decoupling out of the box. It is the design of the system that does that. Though some approaches make it easier to fit :)
Wanted to mention the video Aaron from Petabridge did on this topic. Check out his video: th-cam.com/video/ZUiuh_n6HKg/w-d-xo.html
I love both of these videos. Sometimes it's the really deep, technical discussions that have a huge impact on the way I think, and sometimes it's videos like this that simply offer a different want to think about building software that really change that way I approach things. Another really important idea that you've espoused is concept of "tradeoffs". Allowing myself to entertain ALL solutions (even those people on Twitter swear never to do) and "intentionally" choose what offers the best balance at the moment sounds simple, but can be really difficult when learning (and trying not to shoot yourself in the foot).
Ya I was aware I left that out. I plan on making a video explicitly talking about it with examples. But ultimately the tradeoff between option vs cost on laying the ground work for those options in the future.
CQRS is more as you describe here. It can be exactly what you are saying but I have found in context of manufacturing applications (This is what I learned over the last quarter of a century :) ) it can also mean and apply differently. In my effort what I have the last couple years, getting major monolith broken down in a SOA construct and in a construct where I do have a part of the software with high response requirements and a part where data needs to be available to many other services and business parts I see it this way:
CQRS is a separation between C as "Command and Control" and Q as "Query in sense of reporting and analytics" ...therefor a want to keep the C part close to the production area. Probably OnPrem up to the edge at max. (all data that I need to produce or manufactore parts in seconds or minutes ...just in time (not realtime but ...almost :) ) and the Q part of data can be in different formats find there way in some kind of query optimized db, data lakes of whatever you call it. Available for everyone and everything decoupled from the real manufacturing process.
Appreciate the high quality videos you put out. There's so much content for beginners but not so much for those with a few years experience.
Just a thought on the CQRS portion of this video, have you had a look at Marten or similar library? Not always the 'right' choice It could act as a great demonstration of how simple event sourcing could be when you don't over complicate things.
Yes, I'm aware of it. I haven't used it for anything significant but I'll see if I can get it into a video.
A great simple explanation of software architecture that I totally agree with!
Thanks!
Great to hear!
This channel is basically a gem.
Thanks!
This is all well and good. I like what your saying but I'm having a hard time putting that to a practical use of something I've interacted with in the past. If I were to rebuild that system, for example, could you show some examples?
I tend to use the term "systems architecture" when I'm on a system level (components, integrations, services etc), and "software architecture" when I'm at the software level (clean architecture, layers, SOLID etc). What's your opinion on this?
Ya, I can see that. I tend to avoid the term "distributed system" when talking about an application because I think most tend to view it in the sense of a distributed infrastructure, eg database.
I'm not convinced that using message passing instead of a function call automatically buys you "lower coupling". Maybe at best it's a form of "hidden coupling" since it's now harder to trace.
Passing messages via a durable message broker removes temporal coupling. Sender and Receiver don't need to be online/available at the same time. Publish/Subscribe patterns allows the publisher to be decoupled from the consumers. Publisher is totally unaware of who is subscribing or what they are doing with the event. Is it harder to visualize (or trace) calls between messages, it can be without distributed tracing.
Nice video, simple and concise.
Don't think that monolith has to have tight coupling. Perhaps its more tempting to introduce coupling.
It doesn't. I talk about this in a couple videos, this being one: th-cam.com/video/VGShtGU3hOc/w-d-xo.html
In a monolith, using one database, if i start isolating/decoupling by module/bounded context (isolating repository interface to its corresponding module) would i lose entity relationship to some extent in the database and risk database integrity?
Or should i share repository interface between modules so each can set its relationship to keep db integrity?
Or should each module hide it's repo interface and expose only service interface for retrieving some entity for the other module that needs it?
How important is database integrity in a modular monolith?
You can keep constraints with the knowledge that you know everything is on the same physical database. I don't actually run into this problem with integrity even without constraints
Amazing explanation!
Keep it up!
Thanks 👍
When is CQRS/Mediatr overkill?
CQRS handlers stay at application service layer,the don't have to contain domain logic.Does not they?Thnks!
Depends. Often times they can delegate to domain objects or if not complex can be simply viewed as transaction scripts and work with data models and persistence.
@@CodeOpinion do I apply it correctly? the cqrs handler queries the db/repo to construct the domain models and call the methods/services (domain layer) and then saves the changes back to the db.
So, is Messaging a Silver Bullet that solve all distributed systems issues?
Of course not. It's a way to communicate between logical boundaries to prevent tight coupling. It gives you options for dealing with availability, failures, resilience, etc.
@@CodeOpinion What other solution could help to prevent tight coupling?
@@ruekkart Messaging is very versatile solution in general and applicable nearly everywhere. However it does bring complexity initially, especially if developers are unfamiliar with it (like Derek mentioned). Other options do exist but potentially are equally difficult in different areas. For example microservices resolve a lot of those issues if implemented correctly. Fault tolerance in this case, with services that rely on chain of calls with either HTTP or RPC is something to resolve separately, and there are more cases. I do agree with Derek that design of bounded context is very important either way, since communication between service is something that can be worked on, though it is better to decide on it from the start due to later complexity.
TLDR: I don't think that any architecture in itself resolves decoupling out of the box. It is the design of the system that does that. Though some approaches make it easier to fit :)
There are never any silver bullets, no matter what the topic.
It's a good enough bullet I'd say. Whatever it means for you.
well explained!
Thanks!
👌