Modular Monoliths are the new Graal

2022 06 02 head

A modular monolith is a software design approach in which a monolith is designed with an emphasis on interchangeable and potentially reusable modules.

A modular monolith can be split in the future into a set of microservices.

Delay the split as long as you can. Microservices have a steep price tag during operations.

A modular monolith provides:

  • Independent and parallel development approach.

  • Diminish coupling and improve cohesion. The interfaces are better documented and thinner.

  • Better observability.

Benefits of Modular Monoliths

Adopting the modular approach for monolithic applications can have benefits in a few key areas, including better-organized dependencies, increased code reusability, and increased code observability.

Increased Reusability

For large development teams, developing modular components of an application helps to increase reusability. Modular components can be reused and repurposed and can help teams establish a single source of truth. This can lead to faster and more consistent development.

Better-Organized Dependencies

Because modular monoliths make individual functions more independent, they, by nature, make dependencies more organized and visible. This makes it easier for developers to easily assess which parts of the application require which dependencies.

Increased Observability

Developing with modularity in mind means code is more accessible to developers. For Java developers in particular, interface classes and their requisite Javadoc comments help to enhance accessibility and interoperability for developers who may need to work with the modularized function.

Monolith Benefits Modular Monolith Benefits

Low operational complexity.

Low operational complexity.

Can be more secure than microservice application.

Can be more secure than microservice application.

Easy to manage database consistency.

Easy to manage database consistency.

Less complex than microservice application.

Less complex than microservice application.

Monoliths are usually a nightmare to maintain.

Developed code is reusable.

Often called big ball of mud.

Has better-organized dependencies than a standard monolith.

Observability is often low.

Better code observability than a standard monolith.

When to Use a Modular Monolith

Any time a developer is working on a monolithic application, using principles of modularity can help them to improve the processes for their team. Whether that means making dependencies more manageable within the application, improving developer interoperability on the modular components of that application, or adding modular components to the house repository, embracing modularity can have a positive impact on teams.

For the application itself, embracing modularity can help to organize dependencies, making it easier and less time-consuming to change components within the system.

Good practices shall be applied to refactor the application [1, 2, 3, 4].

Why should you consider a modular monolith instead of microservices?

Microservices architecture certainly provides a good solution for multi-team development.

Sadly, organizations are seldom aware of the associated high DevOps costs. Often a modular monolith would be more cost-effective and still support parallel development. Later, if necessary (Meaning that there are tens of thousands of concurrent users), you can migrate to a distributed service or microservice architecture.

I often see companies jumping on the microservice train and complaining later about the costs of their solution.

I strongly advise Think big, Start small.

When Not to Use a Modular Monolith

Of course, just as microservices are not one size fits all solutions, neither is modularity.

For developers working on small projects with small development teams, developing their code in a modular way may not be worth the added time or formality.

Final Thoughts

Architecture approach for modular monoliths or microservices is Domain Driven Design [5, 6, 7].

If you are like many Java developers who are still working on a monolithic application, then employing modularization best practices can help make your application achieve some benefits of microservices without the associated cost of refactoring.

However, modular monoliths have significant shortcomings when compared to microservices — especially in terms of continuous testing, integration, and deployment.

References

[1] R. C. Martin, Clean Code. Prentice Hall, 2009 [Online]. Available: https://www.amazon.com/dp/0132350882

[2] R. C. Martin, Clean Architecture. Pearson, 2017 [Online]. Available: https://www.amazon.com/dp/0134494164

[3] M. Fowler, Refactoring, First. Addision-Wesley, 1999 [Online]. Available: https://www.amazon.com/dp/B004PQQRK2

[4] A. Scott and P. J. Sadalage, Refactoring Databases. Addison-Wesley Professional, 2006 [Online]. Available: https://www.amazon.com/dp/B001QAP36E

[5] E. Evans, Domain-driven design. Addison-Wesley, 2004 [Online]. Available: https://www.amazon.com/dp/0321125215

[6] V. Vernon, Domain-Driven Design Distilled. Addison-Wesley Professional, 2016 [Online]. Available: https://www.amazon.com/dp/B01JJSGE5S/

[7] V. Vernon, Implementing Domain driven Design. Addison-Wesley Professional, 2012 [Online]. Available: https://www.amazon.com/dp/B00BCLEBN8