Anybody has built a modular monolith? If yes: what were the design principles you used (i.e. request/response via interfaces, events on an in memory event bus for decoupling etc.)?
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (9)
What precisely is a modular monolith? Sounds like a quadratic circle to me.
:-) The idea of building modular applications is decades old. Unfortunately, many monoliths ended up being big balls of mud, full of spaghetti code.
More recently, microservices were proposed as a solution, with the following claimed benefits:
Yet, the downside of a design that uses microservices is the additional operational complexity. Effectively, you have to manage many web servers. You can get some of the benefits of microservices without that downside by building a modular monolith.
A modular monolith uses in-process communication between modules. In contrast to that, microservices use remote communication. That's the big difference.
The downside of a modular monolith is that it doesn't support independent deployability of the services. But in enables independent development by different teams.
But what is the advantage over objects? I never was a fan of microservices, as they leave you with what´s in the box. Using classes let´s you choose an object that does 95% of what you need. Usually it is effortless to derive a new class and just implement what´s missing.
Most of the benefits you get without the downsides. As objects are strictly separated with only a narrow interface, you do not even recognize changes most of the time.
And we had some fairly large applications (>60.000 lines of own code) that needed some update after years. If your hierarchy was good, most of the changes had been done within days.
If that worked for you, great. I wonder if there were certain rules in your codebases. For example: could the UI access business logic, and the business logic the UI as well? Probably not (I hope). Maybe there were clusters of objects, and you accessed only one of them and so on. Modules make these structures explicit - sometimes simply using packages or similar language constructs. A module is a cluster of objects with a well defined interface.
I cant remember that we had any trouble organizing the data flows. Usually you want to keep your interfaces narrow and the class free of any dependencies. So you use callback functions to connect your UI to the business logic.
Think of a calculation tool with numerous inputs elements. You build a class that creates all or some of your input elements. The class has only three callbacks:
When you use the class, you CAN apply these callbacks, but you don´t need to.
If the user inputs some data, the class collects all the data from the UI. If a callback is installed, it sends a JSON object with all the data. Or, it just sends a message that new data have arrived and lets the external logic grab the data they need directly. But in any case you do not need to know, WHO installed the callback.
So, you can establish direct connections between the business logic and an UI this way, but often you will use some kind of dispatcher to organize the data flow more explicit. So, the dispatcher installs the callback and gets informed, when a user input happend. Now he can decide, how to handle the message.
I know that there are lot´s of applications, where each button has it´s own event function. That brings you this kind of spaghetti data flow we should avoid. But if you start developing your UI based on classes, this is a way to organize the dataflow too.
You may check out this project where I tried to build modular monolith based on principles of DDD.
How do you organize the "common sense" in this kind of infrastructure? I assume, there is some kind of eCommerce application locally that will supply some data, so you may need to know some detaily about the data organization. Modules need to know the currency you are using or simply understand each other. I assume you do not want those implementation details in the local code?
I've had a look at it. Pretty impressive in its scope. I had a similar idea to use Spring Events to communicate between the modules. Greetings from/to Munich.
I have implemented communication via Spring Events in this fork:
It's a bunch of services that can be deployed either as a monolithic application or as microservices (docker compose or kubernetes).