Monolithic versus microservices
Now, we will discuss the advantages and disadvantages of using monolithic applications and how microservices improve a specific project by giving a basic example.
Imagine a taxi platform like Uber; the platform in this example will be a small one with only the basic things in order to understand the definitions. There are customers, drivers, cities, and a system to track the location of the taxi in real time:
In a monolithic system, we have all this together---we have a common database with the customers and drivers linked to cities and all these are linked to the system to track taxis using foreign keys.
All this can also be hosted on different machines using master-slave databases; the backend can be in different instances using a load balancer or a reverse proxy and the frontend can use a different technology using Node.js or even plain HTML. Even so, the platform will be a monolithic application.
Lets see an example of possible problems faced in a monolithic application:
- Two developers, Joe and John, are working on the basic taxi example project; Joe needs to change some code on drivers and John has to change some code on customers. The first problem is that both the developers are working on the same base code; this is not an exclusive monolithic problem but if Joe needs to add a new field on drivers, he may need to change the customer's model too, so Joe's work does not finish on the driver's side; in other words, his work is not delimited. This is what happens when we use monolithic applications.
- Joe and John have realized that the system to track taxis has to communicate with third parties calling external APIs. The application does not have a very big load but the system to track taxis has a lot of requests from customers and drivers, so there is a bottleneck on that side. Joe and John have to scale it to solve the problem on the tracking system: they can get faster machines, more memory, and a load balancer, but the problem is that they have to scale the entire application.
- Joe and John are happy; they just finished fixing the problem on the system to track taxis. Now they will put the changes on the production server. They will have to work tonight when the traffic on the web application is lower; the risk is high because they have to deploy the entire application and not just the system to track taxis that they fixed.
- In a couple of hours, an error 500 appears within the application. Joe and John know that the problem is related to the tracking system, but the entire application will be down only because there is a problem with a part of the application.
A microservice is a simple, isolated entity with a concrete proposal. It is independent and works with the rest of the microservices by communicating through an agreed channel as you can see in the next picture:
For developers who are used to working on object-oriented programming, the idea of a microservice would be something like an encapsulated object working on a different machine and isolated from the other ones working on different machines too.
Following the same example as before, if we have a problem on the system to track taxis, it would be necessary to isolate all the code related to this part of the application. This is a little complex and will be explained in detail in Chapter 9, From Monolithic to Microservices, but in general terms, it is a database used exclusively by the system to track taxis, so we need to extract the part for this purpose and the code needs to be modified to work with the extracted database. Once the goal is achieved, we will have a microservice with an API (or any other channel) that can be called by the rest of the monolithic application.
This will avoid the problems mentioned before---Joe and John can work on their own issue because once the application is divided into microservices, they will work on the customer or driver microservice. If Joe has to change code or include a new field, he will only need to change it in his own entity and John will consume the drivers API to communicate with it from the customer's part.
The scalability can be done just for this microservice, so it is not necessary to scale the entire application by spending money and resources and if the system to track taxis is down, the rest of the application will work without any problems.
Another advantage of using microservices is that they are agnostic to the language; in other words, it is possible to use different languages for each microservice. A microservice written in PHP can talk to others written in Python or Ruby because they only give the API to the rest of the microservices, so they just have to share the same interface to communicate with each other.