Breaking a monolithic architecture based application into various microservices and creating an installer to start all the services

Hello guys, in this post I will explain how you can break your monolithic architecture based application into different services and also I will show how you can start all the components by taking care of their dependencies. This will be a basic guide only as your application might be having some more dependencies. But I will make sure this post will give you at least some basic idea about how you can proceed. Before we dive into this let's have some idea about what is monolithic architecture and discuss some of its pros and cons.

In Monolithic architecture, all the components of the application are tightly coupled together. In this type of architecture, all the components are interconnected and dependent on each other. Even a small change in any one particular component might need rewriting the entire application as they are tightly coupled together. But on the good side applications based on this architecture are easy to develop, test and debug.

Lets us take an example of a simple contactlist application. Consider this to be a very simple application having an interface to add and show contacts, an API to add and fetch contacts from the database and finally our database.
So if we follow monolithic architecture then our application will look something like this

As you can see in the diagram both interface (WWW) and API are contained all together in the same application. Even for a small change in any of the components, we need to test the entire application as they are bound together. Also, this is not much scalable as adding more code to any on the component will make the entire application difficult to understand for fresh people who will try to work on this. One more problem with this type of architecture is that next generation will be bound to follow the legacy code as in monolithic architecture this is very difficult to change the technology or language or framework because everything is tightly coupled and depend on each other.

Now let's move to the microservice based architecture and to start with let's break our existing contactlist application into two different services say WWW and API which will be independent of each other.

So as you can see in the diagram above our application has now two different and separate components (say services). Each of these services can run independently on the same machine or different machines but in either case, they have their own separate processes. These services communicate with each other using some common protocols like REST. One of the major advantages of this microservice based architecture is that now as they are independent of each other so they can be maintained by individual teams which will make faster to develop and much more easier to understand and maintain. Also while using this service based architecture developers are no longer bound to follow the legacy code and they can choose whatever technology is best suited for their service.

Now as we got familiar with both the architecture lets start breaking our monolithic application into different services. Here is the source code of the sample monolithic application that we will be breaking into different services.

This is a very simple contact list app where a user can add and see their contacts. So in this application, there are basically two parts WWW and API. WWW is responsible for interacting with the user and make API calls which are responsible for database operations like adding and fetching data. In this sample application, I have added just two API
routes one for fetching contacts and another for adding new contacts but you can have as many as you want like editing, deleting etc.

I prefer using docker containers to run my applications and also this will give us bit more feeling of separations when we will break this application into different services so we will be using docker containers throughout to run our application and services in this post. If you have any doubt about running your application inside a docker container please go through my previous post on this.

So right now in the sample application, a single node server is running inside the docker container and both WWW and API are running on the same server. Our mongo database in this sample application is already running inside a separate container and being accessed from our application. So our primary goal for this tutorial will be to have both these services WWW and API running on single containers independently. And as WWW is dependent on API which in turn is dependent on our database so we should have some way to start our containers in a sequence so that this dependency is not broken for any of the services. So I will also explain in this post how we can take care of this.

So let's start by first separating the API from our main application. So for this create a separate copy of the entire application and then run it on a separate container. Now you will see you got an exact copy of the same application just running in a different container. Now we want our main application WWW to use this API instead of using one that is running on their own server.
For this just change the address that is being used in the $http to get and post contacts.

Now when we restart our main application this will start using the new API from the separate container. Please make sure container having the API service is already running before starting your main application.

So now as we don't need the WWW codes in the API container so just delete the public folder from it. So now we have our API service running separately in a single container. Similarly, as WWW container won't need its API so we can remove all the API codes, models and routes from it and we will have a separate container having WWW service running on it.
So now we have successfully divided our monolithic application into different separate services and hence shifted to a micro service based architecture.

Now we will create an installer which will start all these Services(WWW, API, Database) for us and also take care of the dependencies between them. The most important thing that we should keep in mind is that while using an installer to start all the services we won't be knowing their IP addresses until they are started so we cant hardcode the apiURL in the controller in the way we did above. So we should basically store the IP address of all the containers and pass it as some environment variable to other containers so that they can use it to communicate with them.

So in order to pass the environment variable among the containers, we will be using --link flag while running the container. Using --link flag we can securely transfer information about one container to another container. All these information will be stored in the environment variable of the container being started. We can easily access all envs of a container inside our services using the process.env.

Now we will create an installer file which is basically a shell script in which we will write commands to start our service containers. In order to take care of the dependencies we will first start the database container then API and at last our WWW.

Before running the installer make sure your API, WWW, and all are in the same folder or else change the path in the installer accordingly. Now when you will run this installer you can see in your terminal that installer is starting all the services one by one and finally our app will start.

Here is the entire source code of this tutorial. You can play around with the installer script and add some more features to it like options to restart the application or remove all the containers.

I hope you have got some basic idea about monolithic and micro service based architecture and how you can break your existing monolithic application into different services. If you have any queries feel free to write this down in the comment box.


Post a Comment

Popular posts from this blog

Using ansible for deploying applications to aws cloud

How to integrate a payment gateway into your WordPress website for donations without using woocommerce

How to use s3 bucket with node.js