How modular can your monolith go? Part 7 - no such thing as a modular monolith?
architecting modular monolithThis article is the seventh in a series of articles about modular monoliths. The other articles are:
- Part 1 - the basics
- Part 2 - a first look at how subdomains collaborate
- Part 3 - encapsulating a subdomain behind a facade
- Part 4 - physical design principles for faster builds
- Part 5 - decoupling domains with the Observer pattern
- Part 6 - transaction management for commands
Quite some time ago, I wrote about how there’s no such thing as a microservice. I explained how the term ‘microservices’ is a shorthand for ‘microservice architecture’, which is an architectural style that structures the application as a loosely coupled set consisting of two or more components (a.k.a. services). As a result, a service cannot exist in isolation; it must be part of a larger whole. In this article, I explain why there’s no such thing as a modular monolith and why the term ‘domain-oriented component architecture’ might be a better choice.
What’s the monolithic architecture?
The monolithic architecture is an architectural style that structures the application as a single component, such as a single WAR file or executable JAR.
The component implements all of the application’s subdomains/bounded contexts.
The component’s internal architecture is a black box
From the perspective of the application (or system) architecture, each of its constituent components is a black box. A component’s details are hidden behind its API. Given, therefore, that the term ‘monolith’ is shorthand for ‘monolithic architecture’, it follows that there’s no such thing as a modular monolith(ic architecture).
Modular monolith => modular components
When we use the term ‘modular monolith’, what we are really describing is the internal architecture of a component. The sole component of a monolithic architecture is likely to be large so modularity is especially important. However, there’s no reason why the services within a microservice architecture should not also be modular. In particular, some services might consist of multiple subdomains/bounded contexts owned by different teams. The problems that the ‘modular monolith’ pattern solves are not necessarily unique to the monolithic architecture. Consequently, perhaps a better term is ‘modular component’.
Modular components => domain-oriented components
Now that we have looked at why, perhaps, ‘modular component’ is a more accurate that ‘module monolith’, let’s now look at why the adjective ‘modular’ is not the best choice for the architectural style that we are trying to describe.
A traditional monolith can have a well-defined structure
Monolithic applications are often described as big balls of mud. To quote Foote and Yoder, the authors of that pattern, such a monolith is a “haphazardly structured, sprawling, sloppy, duct-tape and bailing wire, spaghetti code jungle.” However, there’s no reason for a monolithic application to be a big ball of mud. It could have a well-defined structure consisting of layers, which themselves are comprised of modules.
For example, here’s the FTGO monolith:
This monolith is comprised of four layers: main
, web
, domain
and persistence
.
The web
, domain
and persistence
layers consist of domain-specific modules.
The lack of modularity is not the problem.
Real problem: The layers and modules are not aligned with the subdomains/bounded contexts
One actual problem is that the layers and modules are not aligned with application’s subdomains/bounded contexts.
For example, it’s common for the layers to be technical: web
, domain
and persistence
.
As a result, a subdomain/bounded context will typically span multiple layers and modules.
Real problem: The layers and modules are not aligned with the teams
Another actual problem is that the layers and modules are not aligned with the teams that own the subdomains/bounded contexts. As a result, teams need to make changes across multiple layers and modules to implement a feature. It’s an architecture that reflects a traditional siloed organization rather than a modern organization one that’s structured using Team Topologies.
Big idea: organize a component around the domains
The big idea with the modular monolith (component) pattern is that its top-level organizing principle are the domains/bounded contexts. For example:
In this architecture, the monolith consists of modules, such as customers
and orders
.
Each module, in turn, consists of layers, such as web
, domain
and persistence
.
As a result, the application architecture and the teams are aligned.
Better name: domain-oriented component architecture?
Arguably, the term domain-oriented component
or even domain-oriented component architecture
is more accurate than modular monolith (component)
.
What do you think?
Need help with accelerating software delivery?
I’m available to help your organization improve agility and competitiveness through better software architecture: training workshops, architecture reviews, etc.