We have seen in the previous articles how having Microservices could be advantageous for your business and code alike. Now that doesn’t happen every day. Lets now move on and see how we can perform the transition from Monolithic to Microservices. It is important to isolate the functionality in the right way, lets see that.
Functionality Isolation Criteria
Broadly speaking we need to be considering following
- Team Structure
Looking at code of the existing Monolithic we could easily identify the parts of the code that might require to be routinely modified. These could be modules handling product inventory that requires different measuring unit support to be added frequently. However there might be some code that requires the functionality to be changed frequently like the module calculating Taxation for corporate entities. There is a subtle difference between the both but a rather important one. Pick up up the modules falling under any of the two categories and isolate them to be independent. This would require a rather separate discussion and we shall come to it in one of our next articles.
You want the teams to be well synchronized and luckily with Microservices this isn’t much of a problem and comes naturally if the isolation and design has been done well. Only thing that you have to take care of is that you should not be having teams that are a combination of technology or domains [database vs. inter process communication]. So this is rather interesting that we are letting an outside world real life factor impact our code transitioning process. In some ways I feel that it is not that big a surprise since we are trying to move from Monolithic to Microservices – a partial reverse engineering in some terms. So the true Microservices actually have well aligned teams and we just absorbing the same attributes in our process.
As briefly mentioned in the last point that teams should not be spanning across technologies – we need to ensure that the code itself should also be not spanning across multiple technologies. Keep it simple. As these factors are dependent on each other you see.
Let’s quickly see what are some sure shot characteristics of a good Microservice.
- Industry Standard Data Formats
- Industry Accepted Communication Protocols
- Loosely Coupled [my favorite, I can personally live with the rest, although you shouldn’t keep that option]
It is important to understand that apart from the last characteristic the rest two are not binding in any way. However there has to be a business case based implementation for it. If you have a choice then the first two characteristics should be adhered to. If we try to stray away from the first one then the chances are that we will end up adding extra code / use a framework that would make it not loosely coupled. Same would be for the second characteristic. And these are not restrictive by any means as for the industry standard data formats we have XML and JSON available with Microsoft stack. For communication protocol we have widely accepted SOAP and REST.
Domain Driven Design
It can play a very important role and be a potential ally in our transition process. During the process of isolation we can rely on following factors for our Domain Model Design:
- Business Model – restrict all functionality related to only one of these in one Domain Model
- Loosely Coupled – as the name suggest there should not be a dependence on other modules
- Sans framework – should not be dependent on any infrastructure frameworks else it won’t be reusable.
- Reusable – this would come naturally once the above points are taken care of. This could be your indicator whether everything went well or not.
Although it looks rather simple and trivial, but this is not a small exercise. Once done, it can be used to review and execute another pass as required over the process of breaking down the system as per the domain model design. Another factor that can be considered is the number of interactions across entities. Once the first model is ready try to identify a model that communicates with more than the average communication points. This would be in comparison to the rest of the models. If found then you have a case for another pass and the first suitable candidate to perform this activity again.
If the point of more communication points seems little too much to you, just wait a while and you would understand where we are coming from. We have to keep it in mind that we are gunning vertical code isolation here with respect to the final deployment. If this vertical isolation is not attained then it means that we missed the spot.
The process could seem daunting in the beginning for even medium scale applications in the beginning. In my opinion the whole process of transitioning should be as simple and satisfying as the final Microservices itself. We can take help from nature for an analogy here. Just imagine the process of splitting wood with an axe. Don’t be tempted to achieve the single blow for the transition. Instead think of a squirrel that is having a peanut. Micro sized, delicately and meticulously.
The safest and easiest approach would be to identify the parts performing the core functionality. This process would identify the boundaries that exist amongst code modules. We would call these boundaries as SEAM. Imagine the soccer ball that has 32 panels stitched together to form a near perfect round ball. It holds the pressure inside stable and uses it to tackle the sudden pressure being exerted from outside in form of a player kick. That is what we want to achieve with our system. Once the seams are identified we have the first phase done for us nicely.
Let’s Do It
Below is the current database schema for a Holiday package application. For the sake of simplicity we are not going into the User Registration, Payment Modules, Cancellations, Modifications etc. for now. We will simply focus on trying to break down the table relationships in the first part and see if we can achieve the independence for each of the data entity.
As first step let’s break down the who foreign key driven design into independent entities where we will break down some of the foreign key relations. The purpose will be to ensure that Domain Driven model entities can maintain their own store independently.
After that change below is the new design.
So now we can have City, State and Country in one Microservice, Package, BedType and RoomType in another service and Hotel as part of third Microservice.
It is important to note that we didn’t remove the Keys – we just broke down the foreign key relationship as these Microservices will own their data and work independent of the other microservices.
As a result of the above step the three databases we have derived are DB.Country, DB.Hotel and DB.Package. Each of these would a separate database and part of the different Microservice, running independent of the each other.
In our next article we will explore the concept of SEAM in detail and how it impacts the Database Design and Transactions. We will also see communication across our services.