new subscriber here. just found your channel couple days ago. and it's amazing that your videos are very simple yet very practical to the thing I currently working on. thank youu :)
An option is to use "materialized views" which are constructed by consuming events from multiple domains. Let me know if it's not clear and I'll give more info.
Yes, in the context of this video this statement makes sense. However, it is something nuanced. The idea is that if you are in the initial stages of designing a large system, you will probably create a single large domain model and identify the bounded contexts which will give you an idea of how many microservices or "moduliths" you need. The bounded contexts becomes subdomains because after the initial stage, I typically focus on them in isolation. In fact, they would be typically assigned to a specific team / architect. For that team, the original bounded context is actually the entire domain they are responsible for. That is why I was mentioning it is a bit nuanced. Hope it helps.
You can implement the system loosely coupled, but it doesn't mean there's no coupling at all. You can put a service aggregator that connects multiple microservices. If not, tons of heavy lifting will be bourne by the client which is a no no... Especially on mobile where CPU processing is very limited and can be easily compromised. Also, you don't want this heavy lifting written multiple times in different mediums such as iOS, Android, web and whatnot.
Totally agree with everything you said. Some level of coupling is unavoidable and aggregating data for the clients can be a necessity in many scenarios. I feel decisions are rarely clear cut. We always balance pros and cons in the context of the type of system we deliver.
I am curious what other strategies other than event driven solutions can be possible when considering sorting and filtering across different domains. Also you didnt mention about is DDD still useful?
Thank you for the feedback! I think DDD is the core of our profession because we all need to map real world concepts and requirements into some sort of model. Some of us do that just mentally in our own minds. Others go through the effort of documenting such model and I think that is imperative if you are working in a large team or company. Regarding alternatives to using events and creating materialized views that are fine tuned to serve your queries, the other approach is that to let each microservice manage its own subdomain and put an "API Gateway" in front of them. This is simply another microservice or a middleware that will perform aggregation. If the client makes a request that needs filtering and sorting across different domain, it will be the gateway responsible for collecting the data from the different domains and apply filtering and sorting. Obviously you will not match in performance the materialized views approach. In this scenarios, you can also consider a query language like GraphQL. You can watch this other video where I cover the API aggregation topic: ua-cam.com/video/yEzQs1stJhE/v-deo.htmlsi=eg3tu7JubuTskqDg
Hello Good Sir @Marco, This is a brilliant video with very helpful and useful illustration 👍🏾 However, why are you separating Orders, Payments and Shipping ? These all change or are activated for the same reason - i.e. to fulfill an order It makes no sense to separate them into different bounded contexts. This is how one ends up with micro-services (or modules) that are split too much there by creating services that require careful co-ordination between them. This is not to mention the high fan-out that can result from this structure of over-splitting micro-services
I am in total agreement with your advice of avoiding over-splitting and fragmenting the system into too many microservices. Regarding whether my example is fitting or not, I think it depends a lot on the context, functional and non-functional requirements. That said I don't want to advocate for microservices at all cost. The video is based on the premise your goal is microservices to start with. I do have some other videos where I try to answer the question: do you need microservices at all? ua-cam.com/video/13AtILy2g8s/v-deo.html That's said I really like your comment and I want to spare two words on bounded contexts. Even if you decided to move with a monolith, you need to make sure that code is properly modularized. This is where bounded contexts comes very handy. Typically, I don't see non-functional requirements having a lot of weight in the definition of the bounded contexts. Typically, it's enough to look a cohesion and coupling, i.e. we group together classes that tend to co-operate and try to create well-defined exit and entry points for each boundary we define. If we look at it from that perspective, if your payment system is complex enough (and this depends a lot on the requirements you got), there are high chances that most classes have nothing to do with the order. For example, imagine your payment system should allow you clients to save safely payment methods. Typically, these systems are heavily audited and need stricter compliance, e.g. PCI-DSS. Suddenly, you can see we're not talking about something trivial and it's actually the only correct option to segregate Payments in its own services to avoid strict auditing and compliance to affect larger portion of the system. This is just an example and still it holds that, in many cases, it's actually simpler as you described. In that case, we can move with one service and I support that! Thank you a lot for reaching out. Really appreciated!
@@MarcoLenzo Thank you for your response. You are right and i don't think the non-functional requirements matter much over proper cohesion and coupling concerns. My earlier comment applies whether one is dealing with a micro-service or a module in a monolith (P.S. Micro-service are just modules on a high level of organization) It will be correct to separate the Payments to be on its' own (pairing it with an Invoice generator maybe) if the need for compliance for PCI-DSS or SOC2 is high. Yet, for Orders and Shipping, it need not be separated because they are cohesive. Orders will always need Shipping and Shipping will alway need Orders to ship especially for an e-commerce application. It would be incorrect therefore to separate Orders and Shipping into their distinct bounded contexts. Thank you for responding. 🙏🏾
Marco, your videos are excellent. You show you studied what you're talking about. Your material is really good and far much better than those really poor articles that crowd the web, only mixing some keywords and saying nothing. So thank you. I have a question on 2:57 ("Bounded Contexts are equivalent to Microservices")...doesn't it depend on the size of the bounded context? I suppose that there are situations where a bounded context may not match the condition of a pizza size team typically mentioned for microservices, for instance. Don't you think bounded context might be implemented as a group of microservices with high cohesion but low coupling with microservices of other bounded contexts? I think my question might imply that some microservices depends on others (which is against the definition of microservices) but I'd like to hear your opinion. I think, in the end, as you said, architecture is about trade-offs, and, specially in big and long-lived systems, creative ways for managing complexity are a must. I think that part of the problem here is that "microservices architectural pattern" and "domain driven design" refer, at some point, to different parts of the architecture: ddd is a way of linking domain and implementation and microservice architecture as architectural pattern lacks of such concepts (or doesn't pay much attention to them) . Thank you again!!
First of all thank you very much for your feedback! I really appreciate it! You are totally correct in stating that a bounded context is not always equivalent to a microservice. There might be scenarios where the architecture defines microservices that are more fine grained. For instance, you could have a microservice per aggregate if you wished. The aggregate also defines a boundary that is used to identify not only objects that are strongly correlated, but also to reduce associations by electing a root aggregate which is the only object that can be referenced outside the aggregate. The operations an aggregate supports can be easily mapped to the API of a microservice. As usual, it is a matter of trade-off. Sometimes it is not even just a technical matter. It could be driven by choices like the number of teams you need to deploy on the project. However, let me move a point that might strenghten my idea that the bounded context might be a better choice from a purely technical perspective. The aspect that gives me a lot of think is the high cohesion you have within a bounded context. In other words, a lot of the operations you support within the bounded context require the collaboration of all the objects you placed within the boundary. That means that if you model this context as multiples microservices, these operations which are highly cohesive are actually happening by collaboration over the network (API or Messaging). That begs the question: why? Unless there's an asymmetry in terms of load or complexity of different operations within the context, chances are that you might be better off with a single deployable. Again, the devil lies always in the detail, so I'm just making an argument for the sake of debating. Have a great Sunday!
For most businesses (so not the big boy businesses) distributed monoliths are imo the way to go, and you can always add microservices when you need them to scale. The complexity of microservices aren't worth to begin with. There's a lot that can go wrong without a well experienced dev team. The big boys netflix, github, etc. all started with monoliths and added microservices later after having the necessity to do so. Only after a version 1 should you even consider it, after identifying and understanding your domain requirements very well, and this is almost never the case when building a v1
I agree that in most scenarios it is safer to start with a monolith or a small number of services, especially if the team lack experience in dealing with microservices. I also understand that in many scenarios the product evolves rapidly in the first iterations and it takes some time before the requirements stabilize. However, I still think we should invest time defining bounded contexts from the very early iterations, even if you intend to use a monolith. If you do that early, you can build your monolith as a set of modules with well defined and documented interfaces. If you do that, you'll have a much easier transition to microservices if you ever need to go there. Even if you decide to stick to monoliths, it would be easier to increase the number of teams working on it, because you would be creating space for each team to own a well-defined portion of the codebase.
@@MarcoLenzo Thank you for the response. I'm glad we're on the same page. I intentionally left out the modular part to test my understanding with yours. As building a monolith without well defined modules it is going to be a mess and will cause problems later on
Loved this video, but had a lot of trouble to understand some parts of what you said, having to repeat many times what you were saying where not even the subtitles helped, just to understand what you really meant. In my opinion I think the biggest drawback of DDD and microservices are the need to de-normalize databases and manage it all to still keep it consistent. It seems that that monoliths and microservices PROS and CONS are mutually exclusive.
Yeah the trade-off is not simple. The nearest hybrid is the concept of modulith or microlith. This is usually a service that is managing two or more sub-domains which are closely correlated. If the modularization is done right, you can have them coexist to avoid integration over the network. That said, it is still debatable if you should use referential integrity at the DB level across modules. I generally avoid that to give myself the chance to break the modulith into separate microservices in the future.
Hi :) Feedback taken and appreciated! 🙏 I'm doing my best but in the meantime I'm making sure to have all new videos with manually corrected subtitles. I just noticed this video does not have proper subtitles. I'll make sure to update it. I'll also cover other popular videos of mine. Have a great day!
the most incredible thing of this video is to explain such a complex subject in a clear way in only 7 min! wow! thanks a lot.
Thank you very much for the feedback. It's really appreciated!
The way you had explain bounded context for Microservices is very much concisely. Thanks Marco
Thank you. Really appreciated!
Thank you so much for this high-quality content. I hope you have a wonderful rest of your day.
Thank you! Have a great day you too 😊
Bravo Marco, molto chiara come spiegazione !
Grazie!
Many Thanks. You have very well covered all challnging aspects of MicroService Design in 7 mts. Well done !
Thank you 🙏
Awesome walkthrough!! Subscribed.
Thank you very much 🙏
The word from my heart: "Brilliant"
Thank you very much for the kind words! 🙇
This is amazing video mate. Really nice an clear explained. Thanks for sharing.
Really appreciated 🙏
new subscriber here. just found your channel couple days ago. and it's amazing that your videos are very simple yet very practical to the thing I currently working on. thank youu :)
Really glad to hear that!
you have excellent capability to explain the complex problem
Thank you 🙇♂️
how could we get some complex query which need info from different microservices/databases?
An option is to use "materialized views" which are constructed by consuming events from multiple domains. Let me know if it's not clear and I'll give more info.
@@MarcoLenzo Thanks for answer) how about this option Logical Replication: PubSub in PostgreSQL? I think its a great one
Extremely relevant. Brilliant. Thanks.
Thank you 🙏
Great content delivered concisely as usual. 👍
Much appreciated!
Amazing video! Thank you.
I got a question, did you used subdomains as a synonym of bounded context / microservice? if not what's the difference?
Yes, in the context of this video this statement makes sense. However, it is something nuanced.
The idea is that if you are in the initial stages of designing a large system, you will probably create a single large domain model and identify the bounded contexts which will give you an idea of how many microservices or "moduliths" you need.
The bounded contexts becomes subdomains because after the initial stage, I typically focus on them in isolation. In fact, they would be typically assigned to a specific team / architect. For that team, the original bounded context is actually the entire domain they are responsible for.
That is why I was mentioning it is a bit nuanced.
Hope it helps.
This video is gold, so many interesting concepts ❤
🙇♂️ thank you
You can implement the system loosely coupled, but it doesn't mean there's no coupling at all. You can put a service aggregator that connects multiple microservices. If not, tons of heavy lifting will be bourne by the client which is a no no... Especially on mobile where CPU processing is very limited and can be easily compromised. Also, you don't want this heavy lifting written multiple times in different mediums such as iOS, Android, web and whatnot.
Totally agree with everything you said. Some level of coupling is unavoidable and aggregating data for the clients can be a necessity in many scenarios. I feel decisions are rarely clear cut. We always balance pros and cons in the context of the type of system we deliver.
I am curious what other strategies other than event driven solutions can be possible when considering sorting and filtering across different domains. Also you didnt mention about is DDD still useful?
Thank you for the feedback!
I think DDD is the core of our profession because we all need to map real world concepts and requirements into some sort of model. Some of us do that just mentally in our own minds. Others go through the effort of documenting such model and I think that is imperative if you are working in a large team or company.
Regarding alternatives to using events and creating materialized views that are fine tuned to serve your queries, the other approach is that to let each microservice manage its own subdomain and put an "API Gateway" in front of them. This is simply another microservice or a middleware that will perform aggregation. If the client makes a request that needs filtering and sorting across different domain, it will be the gateway responsible for collecting the data from the different domains and apply filtering and sorting. Obviously you will not match in performance the materialized views approach. In this scenarios, you can also consider a query language like GraphQL.
You can watch this other video where I cover the API aggregation topic:
ua-cam.com/video/yEzQs1stJhE/v-deo.htmlsi=eg3tu7JubuTskqDg
Thank you for the video bro!
💪
Hello Good Sir @Marco,
This is a brilliant video with very helpful and useful illustration 👍🏾
However, why are you separating Orders, Payments and Shipping ? These all change or are activated for the same reason - i.e. to fulfill an order
It makes no sense to separate them into different bounded contexts. This is how one ends up with micro-services (or modules) that are split too much there by creating services that require careful co-ordination between them. This is not to mention the high fan-out that can result from this structure of over-splitting micro-services
I am in total agreement with your advice of avoiding over-splitting and fragmenting the system into too many microservices. Regarding whether my example is fitting or not, I think it depends a lot on the context, functional and non-functional requirements.
That said I don't want to advocate for microservices at all cost. The video is based on the premise your goal is microservices to start with. I do have some other videos where I try to answer the question: do you need microservices at all? ua-cam.com/video/13AtILy2g8s/v-deo.html
That's said I really like your comment and I want to spare two words on bounded contexts.
Even if you decided to move with a monolith, you need to make sure that code is properly modularized. This is where bounded contexts comes very handy.
Typically, I don't see non-functional requirements having a lot of weight in the definition of the bounded contexts. Typically, it's enough to look a cohesion and coupling, i.e. we group together classes that tend to co-operate and try to create well-defined exit and entry points for each boundary we define.
If we look at it from that perspective, if your payment system is complex enough (and this depends a lot on the requirements you got), there are high chances that most classes have nothing to do with the order. For example, imagine your payment system should allow you clients to save safely payment methods. Typically, these systems are heavily audited and need stricter compliance, e.g. PCI-DSS. Suddenly, you can see we're not talking about something trivial and it's actually the only correct option to segregate Payments in its own services to avoid strict auditing and compliance to affect larger portion of the system.
This is just an example and still it holds that, in many cases, it's actually simpler as you described. In that case, we can move with one service and I support that!
Thank you a lot for reaching out. Really appreciated!
@@MarcoLenzo Thank you for your response.
You are right and i don't think the non-functional requirements matter much over proper cohesion and coupling concerns.
My earlier comment applies whether one is dealing with a micro-service or a module in a monolith (P.S. Micro-service are just modules on a high level of organization)
It will be correct to separate the Payments to be on its' own (pairing it with an Invoice generator maybe) if the need for compliance for PCI-DSS or SOC2 is high.
Yet, for Orders and Shipping, it need not be separated because they are cohesive. Orders will always need Shipping and Shipping will alway need Orders to ship especially for an e-commerce application.
It would be incorrect therefore to separate Orders and Shipping into their distinct bounded contexts.
Thank you for responding. 🙏🏾
Marco, your videos are excellent.
You show you studied what you're talking about. Your material is really good and far much better than those really poor articles that crowd the web, only mixing some keywords and saying nothing. So thank you.
I have a question on 2:57 ("Bounded Contexts are equivalent to Microservices")...doesn't it depend on the size of the bounded context? I suppose that there are situations where a bounded context may not match the condition of a pizza size team typically mentioned for microservices, for instance.
Don't you think bounded context might be implemented as a group of microservices with high cohesion but low coupling with microservices of other bounded contexts? I think my question might imply that some microservices depends on others (which is against the definition of microservices) but I'd like to hear your opinion. I think, in the end, as you said, architecture is about trade-offs, and, specially in big and long-lived systems, creative ways for managing complexity are a must.
I think that part of the problem here is that "microservices architectural pattern" and "domain driven design" refer, at some point, to different parts of the architecture: ddd is a way of linking domain and implementation and microservice architecture as architectural pattern lacks of such concepts (or doesn't pay much attention to them) .
Thank you again!!
First of all thank you very much for your feedback! I really appreciate it!
You are totally correct in stating that a bounded context is not always equivalent to a microservice. There might be scenarios where the architecture defines microservices that are more fine grained. For instance, you could have a microservice per aggregate if you wished. The aggregate also defines a boundary that is used to identify not only objects that are strongly correlated, but also to reduce associations by electing a root aggregate which is the only object that can be referenced outside the aggregate. The operations an aggregate supports can be easily mapped to the API of a microservice.
As usual, it is a matter of trade-off. Sometimes it is not even just a technical matter. It could be driven by choices like the number of teams you need to deploy on the project.
However, let me move a point that might strenghten my idea that the bounded context might be a better choice from a purely technical perspective. The aspect that gives me a lot of think is the high cohesion you have within a bounded context. In other words, a lot of the operations you support within the bounded context require the collaboration of all the objects you placed within the boundary. That means that if you model this context as multiples microservices, these operations which are highly cohesive are actually happening by collaboration over the network (API or Messaging). That begs the question: why? Unless there's an asymmetry in terms of load or complexity of different operations within the context, chances are that you might be better off with a single deployable. Again, the devil lies always in the detail, so I'm just making an argument for the sake of debating.
Have a great Sunday!
Let's always do alot of good ❤️
Always 😊
For most businesses (so not the big boy businesses) distributed monoliths are imo the way to go, and you can always add microservices when you need them to scale. The complexity of microservices aren't worth to begin with. There's a lot that can go wrong without a well experienced dev team. The big boys netflix, github, etc. all started with monoliths and added microservices later after having the necessity to do so. Only after a version 1 should you even consider it, after identifying and understanding your domain requirements very well, and this is almost never the case when building a v1
I agree that in most scenarios it is safer to start with a monolith or a small number of services, especially if the team lack experience in dealing with microservices. I also understand that in many scenarios the product evolves rapidly in the first iterations and it takes some time before the requirements stabilize.
However, I still think we should invest time defining bounded contexts from the very early iterations, even if you intend to use a monolith. If you do that early, you can build your monolith as a set of modules with well defined and documented interfaces. If you do that, you'll have a much easier transition to microservices if you ever need to go there. Even if you decide to stick to monoliths, it would be easier to increase the number of teams working on it, because you would be creating space for each team to own a well-defined portion of the codebase.
@@MarcoLenzo Thank you for the response. I'm glad we're on the same page. I intentionally left out the modular part to test my understanding with yours. As building a monolith without well defined modules it is going to be a mess and will cause problems later on
Loved this video, but had a lot of trouble to understand some parts of what you said, having to repeat many times what you were saying where not even the subtitles helped, just to understand what you really meant.
In my opinion I think the biggest drawback of DDD and microservices are the need to de-normalize databases and manage it all to still keep it consistent. It seems that that monoliths and microservices PROS and CONS are mutually exclusive.
Yeah the trade-off is not simple. The nearest hybrid is the concept of modulith or microlith. This is usually a service that is managing two or more sub-domains which are closely correlated. If the modularization is done right, you can have them coexist to avoid integration over the network. That said, it is still debatable if you should use referential integrity at the DB level across modules. I generally avoid that to give myself the chance to break the modulith into separate microservices in the future.
wow. whole book in 8 minutes. please l need explanation on combining DDD and Event driven
I will expand for sure in some upcoming video. Stay tuned! 🙂
@@MarcoLenzo l have subscribed and hit bell button for upcoming video
Services aggregator video please!
....[subscribed]
Sure. I put it down in my list 🙂
@@MarcoLenzo Great videos, thank you. I'm sure the channel will grow quickly if you keep putting these quality videos out as regularly as you are.
By the way, created the video on aggregation -> ua-cam.com/video/yEzQs1stJhE/v-deo.html
@@MarcoLenzo I watched that shortly after it came out, thanks
Subscribed.
Thank you!
Very informative, thank you so much sir.
The music is disturbing, please remove it in upcoming videos.
Subscribed
Ok I will remove it altogether or lower it substantially. Thanks for the feedback
The bass in the background music is pretty annoying especially when playing at 1.5X speed.
Thank you for the feedback. I'm just starting and I didn't consider background music could be annoying. I'll rethink it.
Ive got to say that the music didnt distract me at all, but I dont get bass out of these speakers. Maybe cut down the bass but keep the music.
@@alan- Yeah I had the track in the second part a bit more punchy and I guess I just needed to equalize it better.
Your content is super rich i wish you could improve the English accent, said with love and feedback ♥️🙏🏻 loved your video a d find it super useful
Hi :) Feedback taken and appreciated! 🙏
I'm doing my best but in the meantime I'm making sure to have all new videos with manually corrected subtitles.
I just noticed this video does not have proper subtitles. I'll make sure to update it. I'll also cover other popular videos of mine.
Have a great day!
DDD - just say no!
What approach do you use for modeling instead of DDD?
Very well Explained. Enjoyed it, but please water those poor plants🪴🫣
Lol 🤣 You killed me. Relayed the comment to my wife and it's challenge on! She promised next videos you'll see a difference ahahah