Traditional applications are often referred to as monolithic. In a monolithic application, all of the functionality is deployed as a single unit.
This itself is not a bad thing. Deploying a single unit is easy to manage. The problems come from not having a good separation of concerns. In a cloud native application, it is important to have a good separation of concerns by splitting the system into separate components that can be developed and tested independently. The idea is that if each component only has one reason to change, then changes do not cause side effects to other components. This allows different developers to work on different components at the same time and quickly, as they are not stepping on each other’s toes.
Unfortunately, many monolithic applications do not separate concerns sufficiently and they become “big balls of mud” that are difficult to change, killing developers’ productivity.
I joke that any book about cloud native can be measured by the time it takes to mention Martin Fowler, who popularized microservices in the early 2010s. My colleague Jeff will be disappointed I only managed to get to the third chapter. I learned about microservices from a talk by James Lewis, the often-forgotten co-coiner of the term. At first, I did not get it, but when I applied it to my work, I saw the value.
I handled an application that allowed users to submit data and produce reports on the data. If a change was needed to the reports, the whole system needed to be deployed, and at that time, no one could submit new data. By breaking apart the monolith into a data submission and a data reporting service, I could deploy changes to reporting without any interruption to submission. Similarly, I could change the submission service without interpreting reporting. This is a simple example, but it led to much happier users and made my life a lot easier as deployment became a lot easier.
Microservices are now a widely adopted approach to building modern, scalable, and resilient cloud native systems. However, because they are deployed and managed independently, there is an overhead of complexity.
When beginning an application, it may not be clear where the boundaries are, and it is not necessary to jump to microservices straight away; the important part is to separate the application into modules that have the potential to be deployed independently. If an application is initially developed as a single modular monolith, this is not a problem. As the application grows and different components need to be deployed or scaled independently, a well-structured monolith can be broken into microservices later.
However, for the rest of the book, I will use microservices synonymously with components as the building blocks of your cloud native applications. To go into much more depth on the subject of microservices, I recommend Building Microservices by Sam Newman (O’Reilly).