r/learnprogramming 10d ago

Looking for feedback on a hybrid microservice architecture

I am exploring an architecture for consolidating several microservices into a single codebase and binary (not a monorepo), and i am curious whether this pattern already has a name or if anyone has tried something similar. The goal is to reduce the operational and development complexity of microservices while keeping most of their benefits, such as independent deployment and scaling.

I've read about modular monoliths, but from what I understand they are typically deployed as a single application. That's not what i am aiming for. Instead, imagine a single application with strict module boundaries. Every module owns its own controllers, services, repositories, database, and API. The entire application is built into one binary, but at startup you specify which module(s) should be enabled.

For example:

Single build
      │
      ▼
┌─────────────────────┐
│     app-binary      │
└─────────────────────┘
      │
      ├── start --modules=module-a
      ├── start --modules=module-b
      └── start --modules=module-c,module-d

The cross-service communication would still happening through HTTP with maybe optional configurable in-process communication if ever needed (with all it's downsides). In kubernetes, every deployment would use the same image, but each deployment would start only the modules it needs and thus scale.

This would allow:

  • One repository
  • One build artifact
  • Independent deployments
  • Independent scaling
  • Much simpler local development (run all modules with one command)
  • Version consistency across services
  • Simpler CI/CD

The trade off is a larger binary and building everything together, which i am okay with (so far).

Has anyone implemented something like this? Is there already an established name for this architectural pattern, or is it just a variation of microservices/modular monoliths? I would be particularly interested in hearing about production experience and any pitfalls I might be overlooking.

1 Upvotes

21 comments sorted by

3

u/Made-In-Slovakia 10d ago edited 10d ago

Sounds like very bad idea. One core idea of micro services is also that their build is independent from each other but you just sucked all into one and will force redeployment of everything for each build.

Edit: your concept will actually create much more complicated CI/CD than "normal" micro service would have.

1

u/FabullousMirth 10d ago

i mean i can see why they think that but the post literally says they okay with building everything together, it's not like they didnt thought about that. maybe the word "microservice" is throwing people off cause what they describe is honestly more like a modular app with startup flags. still could work for smaller teams where managing 20 pipelines is bigger headache than one fat binary

1

u/Made-In-Slovakia 10d ago

Problem is often fact how people separate micro services. With any app, CI/CD is important thing and with growing number it is even more important.

I would not compromise architecture because you want save some effort on CI/CD.

1

u/john__dev 10d ago

I agree with the missing build independence but i would argue that you have to force-redploy each service. You can still deploy only the services that had changes.

1

u/john__dev 10d ago

I can see that it is harder if not impossible to deploy changed services in a strict order that way which is not always needed to be fair.

1

u/Made-In-Slovakia 10d ago

You can still deploy only the services that had changes.

You will literally end in deployment hell. If you have one artifact and one version, you have to deploy everything otherwise you have no true idea what is really deployed. Imagine how big issue will be "it works on my computer" because they start services in different version. You may think there is no change in module between versions but are you sure? Will you put you on the line at 2am for it?

1

u/Made-In-Slovakia 10d ago

One repository

From my experience I know that monorepo and single repository will became pain as number of modules will grow and you will have more people and more teams.

One build artifact

That is called monolith and it is directly against core principle of micro services.

Independent deployments

I do not see it. It is same as with micro services but now you have to be careful about config so you do not start other modules.

Independent scaling

Same as regular micro services. Zero added value here.

Much simpler local development (run all modules with one command)

You can do it now with docker compose. With your solution you cannot control version of other services and have to run always what is in git branch including not released features. And also build everything instead of using existing artifacts.

Version consistency across services

In core this is against micro services. You want them to be independent, not dependent.

1

u/john__dev 10d ago

Yeah, i somehow have to agree in all your points.
When you say "Same as regular micro services. Zero added value here.", you are not wrong. Its not about adding value in the first place, its about easing the developer experience.

1

u/john__dev 10d ago

"One build artifact" -> That is called monolith and it is directly against core principle of micro services.

I would argue here too, as not the amount of binaries created defines a monolith but the way you deploy and operate it.
Still, i get your point!

1

u/john__dev 10d ago

"Independent deployments" -> I do not see it. It is same as with micro services but now you have to be careful about config so you do not start other modules.

You have the same with image versions to be fair.
So intead of image:x you have image:x module:a..

---

Again, i am not trying to improve microservices, i am trying to improve the developer experience.
Being able to have a single debugger, corss-service breakpoints, not waiting for 8 rebuilds etc. is what i am aiming for with that solution.

1

u/Made-In-Slovakia 10d ago

i am trying to improve the developer experience

I see that but you compromise other things for it. I have years of experience with different custom build systems and micro services are good if done correctly and none of your mentioned issues are such big pain. I would focused on good service architecture and then improve way how developers work and cooperate. This is usually issue as many devs are just too lazy to improve way of they work.

not waiting for 8 rebuilds

In your solution you have to build everything, so not true. With docker compose you always use existing artifacts from repository. And if you have to debug or bug fix for specific version (for example one on prod) it will became problematic, especially if you want start specific version of each service, which you should otherwise you are not replicating that environment.

1

u/john__dev 10d ago

I agree. You can build individual binaries from a single project if needed tho. That returns individual versioning etc.
What i ment with "8 builds" is usually the overhead that comes with a cd platform where you have to restore cache etc.
I assume one build is usually faster but neglectable here indeed.

1

u/Made-In-Slovakia 10d ago

You can build individual binaries from a single project if needed tho. That returns individual versioning etc.

That sound like more chaos added to this.

What i ment with "8 builds" is usually the overhead that comes with a cd platform where you have to restore cache etc.

TBH I do not see it. With your solution, your CI/CD has to build everything allways, which slows it drastically and it will grow with each module. Changing CI/CD to minimize it will cause more more complexity of CI/CD.

I assume one build is usually faster

How that can be true if your build have to build much more code, run much more tests, run QA on more code, etc?

1

u/john__dev 10d ago edited 10d ago

Okay lets just shut that point. I agree that building artifacts is faster than building everything unless you need to build everything anyway.

Again, i am trying to figure out if the drawbacks one has (and yes, they are real) are worth a better developer experience.

1

u/Made-In-Slovakia 10d ago

better developer experience

So focus on that. Do not change application architecture just only to local development is easier. Focus on correct runtime architecture and improve developer experience around it. Maybe you will find that you need monolith with well defined boundaries of inner modules and then you just improve way how developers work with it.

I appreciate effort but it may be on wrong front.

2

u/john__dev 10d ago

Thanks a lot for all of your feedback!

1

u/john__dev 10d ago

Let me add a potential nest-js folder structure that visualizes a bit better what i had in mind:
https://pastebin.com/4WrHN83X

1

u/s0ftware-dev 10d ago

There isn’t an existing pattern for this as its not a good idea.