Shesha is a brand new, open-source, low-code framework for .NET developers. With Shesha, you can create business applications faster and with more than 80% less code!
I've worked with many different software architectures over the years.
There's one that clearly stands out for its benefits: Modular Monolith architecture.
Modular monoliths blend the simplicity and robustness of traditional monolithic applications with the flexibility and scalability of microservices. I'm tempted to say they bring together the best of both worlds.
The modular monolith architecture allows you to work in a unified codebase with clearly defined boundaries and independent modules. You can have a high development velocity without the complexity of distributed systems.
Today, I'll introduce you to the modular monolith architecture and why you should know about it.
What is a Modular Monolith?
A modular monolith is an architectural pattern that structures the application into independent modules or components with well-defined boundaries. The modules are split based on logical boundaries, grouping together related functionalities. This approach significantly improves the cohesion of the system.
The modules are loosely coupled, which further promotes modularity and separation of concerns. Modules communicate through a public API, and you can learn more about this in my article on modular monolith communication patterns.
But what are the benefits of a modular design?
If we take the example of an apartment booking system illustrated above. During the holiday season, the system is expecting a traffic spike. The bookings and payments modules need to scale so they can be deployed independently. At the end of the holiday season, they can be merged back into a single deployment. Modular monoliths give you this kind of flexibility.
Modular Architecture
Modular monoliths introduce a few important technical challenges that we will need to solve.
To achieve a modular architecture, the modules:
Must be independent and interchangeable
Must be able to provide the required functionality
Must have a well-defined interface exposed to other modules
Is it possible for a module to be completely independent? Not really. That would mean it's not integrated with other modules. We want loosely coupled modules and to keep the number of dependencies low. We can use a few techniques to keep the modules independent, and having good data isolation is one example.
Another factor you need to consider is how strong the dependency is. If two modules are very "chatty", you might have incorrectly defined the boundaries. You should consider merging these modules together.
Remember, a module is a grouping of related functionalities accessed via a well-defined interface.
Having a modular architecture allows you to easily extract modules into separate services.
Monolith First
Microservices have become the most popular architectural pattern in recent years, and for good reason. Microservices offer many benefits like clearly defined service boundaries, independent deployments, independent scalability, and much more.
However, most teams would be better off starting with a monolith application.
A monolith is an architectural pattern where all components are deployed as a single physical deployment unit.
Here's an interesting quote from Martin Fowler:
You shouldn't start a new project with microservices, even if you're sure your application will be big enough to make it worthwhile.
Here are the five main challenges Google identified with microservices:
Performance - The overhead of serializing data and sending it across the network has a noticeable impact on performance.
Correctness - It's difficult to reason about the correctness of a distributed system when there are many interactions between components.
Management - We have to manage multiple different applications, each with its release schedule.
Frozen APIs - Once an API is established, it becomes hard to change without breaking any existing API consumers.
Development speed - Making a change in one microservice may affect many other microservices, which requires carefully planning deployments.
When you factor in the complexity of distributed systems, starting with a modular monolith becomes increasingly compelling. I also recommend reading about the fallacies of distributed computing if you're unfamiliar with them.
Well-defined, in-process components (modules) can be an excellent stepping stone to out-of-process components (services).
Benefits of a Modular Monolith
Modular monoliths have many benefits. So, I want to highlight a few that I consider important:
Simplified deployment - Unlike microservices, which require complex deployment strategies, a modular monolith can be deployed as a single unit.
Improved performance - Communication between modules occurs in-process. This means that there's no network latency or data serialization/deserialization overhead.
Enhanced development velocity - There's a single codebase to manage, simplifying debugging and the overall development experience.
Easier transaction management - Managing transactions in a distributed system is very challenging. Modular monoliths simplify this since modules can share the same database.
Lower operational complexity - Modular monoliths reduce the operational overhead that comes with managing and deploying a distributed microservices system.
Easier transition to Microservices - A well-structured modular monolith offers a clear path to a microservices architecture. You can gradually extract modules into separate services when the need arises.
Modular Monolith vs Microservices
The biggest difference between modular monoliths and microservices is how they're deployed. Microservices elevate the logical boundaries inside a modular monolith into physical boundaries.
Microservices give you a clear strategy for modularity and decomposing the bounded contexts. But, you can also achieve this without building a distributed system. The problem is people end up using microservices to enforce code boundaries.
Instead, you can build a modular monolith to get most of the same benefits. Modular monoliths give you high cohesion, low coupling, data encapsulation, focus on business functionalities, and more.
Microservices give you all that, plus independent deployments, independent scalability, and the ability to use different technology stacks per service.
Choose microservices for the benefits, not because your monolithic codebase is a mess.
Modular monoliths offer a compelling way to structure applications. They balance the benefits of well-organized code, scalability potential, and a smooth path for transitioning to microservices if needed. If you want to improve the maintainability and adaptability of your software, consider exploring modular monoliths.
Want to dive deeper into modular monoliths? Check out these resources:
P.S. There are 2 ways I can help you improve your skills:
Modular Monolith Architecture
This in-depth course will transform the way you build monolith systems. You will learn the best practices for applying the Modular Monolith architecture in a real-world scenario.
This is the complete blueprint for building production-ready applications using Clean Architecture. Join 2,400+ other students to accelerate your growth as a software architect.
I love hearing from readers, and I'm always looking for feedback. How am I doing with The .NET Weekly? Is there anything you'd like to see more or less of? Which aspects of the newsletter do you enjoy the most?
Hit reply and say hello - I'd love to hear from you!
Stay awesome,
Milan
You received this email because you subscribed to our list. You can unsubscribe at any time.
Lightweight In-Memory Message Bus Using .NET Channels Read on: my website / Read time: 6 minutes BROUGHT TO YOU BY Iron Software's Suite Expansion: Unveiling 9 Developer Libraries. Iron Software
Automatically Register Minimal APIs in ASP.NET Core Read on: milanjovanovic.tech Read time: 4 minutes The .NET Weekly is brought to you by: Become a Postman master with Postman Intergalactic
Using Scoped Services From Singletons in ASP.NET Core Read on: milanjovanovic.tech Read time: 3 minutes The .NET Weekly is brought to you by: Become a Postman master with Postman
Getting the Current User in Clean Architecture Read on: milanjovanovic.tech Read time: 4 minutes The .NET Weekly is brought to you by: Blending AI with UI: Crafting LLM UIs in Blazor,
How I Made My EF Core Query 3.42x Faster With Batching Read on: milanjovanovic.tech Read time: 4 minutes The .NET Weekly is brought to you by: How do you choose the right PDF library?
ISSUE #434 24th of November 2024 Hi Kotliners! Next week is the last one to send a paper proposal for the KotlinConf. We hope to see you there next year. Announcements State of Kotlin Scripting 2024
More Time to Write A fully functional clock that ticks backwards, giving you more time to write. Tech Stuff Martijn Faassen (FWIW I don't know how to use any debugger other than console.log) People
Also: Best Outdoor Smart Plugs, and More! How-To Geek Logo November 23, 2024 Did You Know After the "flair" that servers wore—buttons and other adornments—was made the butt of a joke in the
JSK Daily for Nov 23, 2024 View this email in your browser A community curated daily e-mail of JavaScript news React E-Commerce App for Digital Products: Part 4 (Creating the Home Page) This component
What (and who) video-based social media leaves out. Here's a version for your browser. Hunting for the end of the long tail • November 23, 2024 Not Ready For The Camera Why hasn't video
Daily Coding Problem Good morning! Here's your coding interview problem for today. This problem was asked by Microsoft. You are given an string representing the initial conditions of some dominoes.
These two maps compare the world's tallest countries, and the world's shortest countries, by average height. View Online | Subscribe | Download Our App TIME IS RUNNING OUT There's just 3
November 23, 2024 | Read Online Subscribe | Advertise Good Morning. Welcome to this special edition of The Deep View, brought to you in collaboration with Convergence. Imagine if you had a digital