There are two groups. One who loves micro service and the other who does not. Oh, I forgot about one more group, which is kind of in between. I stand there. I want to take the advantages of having micro services at the same time don’t want to bloat the system so that advantages take the U turn.
I would like to give some references before we go to the point.
David Heinemeier, from Basecamp, says he is against the micro services. Check it out here https://open.spotify.com/episode/2s28wHKb1uWPhUasxUUxGL
Malcolm Gladwell in David and Goliath book, says, advantages and disadvantages can go upside down many of the times. Checkout Teresa DeBrito chapter specifically.
Okay, enough. Lets get to the point. Lets say we have one monolithic service, which is the only service for our entire application. Should we divide it into multiple services? No, unless either
- We are unable to maintain the code with the team we have, or
- The computation power we have on the server is not enough.
(2nd can be solved even by scaling horizontally, like adding more servers behind the load balancer)
Think of micro services as just plain functions. Just that invocation of micro service happens on some http request(mostly). So, with this point, when you are building some application, do you prefer all the functions read and rely on global variables? No, I would not do that. That leads to high inter-dependency system. That is not a good design. We need components in our system to have less dependency on the other components. Modular, loosely coupled! I would have more dumb functions — which just take some input and give some output without depending on outside world. Same applies for micro services.
Let’s assume we are building an e-commerce application. As part of it, we need to generate invoices — pdfs. Generating this pdf is something that does not depend on any other part of the application. Lets assume we want to have it as a separate service. We can do it in two ways,
- Pass the order id to it, so that it fetches the order details itself and generates the invoice pdf
- Pass all the details required for generating the invoice, like, products, discounts, total amount, customer details etc. and it just generates the pdf using these details.
I would go with second approach. Reasons are, this service does not have to know about where the order details are stored, if the service which is invoking it already have all the data itself, then it does not make sense to just pass the order id and do another data fetch call. I don’t mean we should always do it this way. But we should prefer this unless there are some exceptions like the data you have to pass to this service is too huge and cannot be sent on network.
David Heinemeier might be correct in his way because people are misusing the micro services. Instead he loves to have one service (or couple more but not many) which is well designed and modular enough, so that the team or the developers can manage the sub modules easily and add more features without any issues. Exhausting the hardware resources we have, can always be solved by adding more instances/servers.
Malcolm Gladwell is right in this case because, if you just divide the services without proper plan, thought process, the advantages of micro services can become disadvantages and haunt you later. So be wise and use the power you have
So, make your micro services as dumb as possible and have very little services to have the idea of other services or the entire system, which means they are not micro any more.