Oct 7, 2023

Microservices without reason

Too many companies default to microservices, and with it comes increasing development and operational costs, a decrease in software quality, and a decrease in team motivation.

Microservices rarely help with actual problems. And no, they certainly do not help with spaghetti-code, which is the biggest misconception of them all. That's why you should have a reason for microservices.

Mastering proper software architecture is key to creating software that can eventually evolve into microservices when there is a valid reason to.

Valid reasons

  • Scaling teams
  • Optimizing runtime costs (after your application starts making money)

Yep, that's it. But what about spaghetti-code you ask?

Spaghetti-code misconception

Let me explain why microservices do not solve spaghetti-code and even introduce spaghetti-code that is more vicious because you do not see it at compile time.

Bad software design leads to messy dependencies in your code. Making a change in a single file requires a cascade of changes in other files. This is caused by bad design, and it's easier to deal with in a monolith, where an IDE and compiler will help you make all necessary changes.

Dependencies do not disappear in a distributed environment, you just do not recognize them anymore. You will start working on nasty bugs after you changed a feature in one service that leads to a bug in another service.

These bugs happen because the services have some kind of business related dependency and interact with each other. Having tightly coupled microservices is the worst kind of spaghetti-code and ends up with bugs and poor performance, with the additional complexity that these dependencies are now hidden in a distributed environment. If someone argues microservices remove spaghetti-code by eliminating dependencies, they are just plain wrong.

Microservice architecture done wrong

Symptoms of a badly designed microservice architecture:

  • Multiple services have to be deployed at once because a shared library has been updated
  • Failure in one microservice leads to cascading failures in others
  • Implementing a new feature requires changes to multiple microservices
  • Stalling a deployment until another microservice has been deployed

If your microservices are strongly coupled, you will have to deploy them as a monolith. This is a common pitfall. Microservices do not solve the issues most companies have. Many developers think that microservices solve bad software design, but in fact, they make it much worse.

Focus on software architecture

The beauty of microservices is that they can be adopted gradually. If you learn and apply software architecture, you can extract parts of your software as microservices with ease. It does not require gigantic upfront planning of how the overall application might work, you just have to create properly designed software, and after you have implemented plenty of features, you can extract a part of it and give it to another team or optimize its runtime cost.

All software architectures have a simple layering concept in common. Have layers where each layer is only dependent upon the next inner layer. To cross from an inner layer to an outer layer, introduce interfaces. That's it.

If your use cases and business entities do not rely on specific frameworks or libraries, it is easy to extract them into a new microservice.

Please read about the following software architectures. This list is my recommended reading order as progressively new concepts are introduced, but all you need to really understand is the first one:

  • Ports and adapters / Hexagonal architecture
  • Clean architecture
  • Domain driven design

If you understand software architecture, you will create easy to maintain and highly adaptive software. Software development is about handling dependencies correctly. Keeping your business logic technology independent will enable you to adopt anything you like whenever it makes sense, e.g., different frameworks, technologies or even new system architectures like microservices.

Conclusion

Just start with a small team on a monolith. Focus on learning and implementing proper software architecture, which enables you to easily adopt tools to solve problems when they come up. Please do not fall into the trap of focussing on tools too much it is not what your software is about, they are tools after all.