Based on my personal experience, here is why I like microservice architecture :
Independent Development:
Different teams can own small pieces of code. Even within the same team, different developers can work on different services and not step on each other’s toes (no more merge conflicts!)
We can use different technology stacks. we can use NoSql database for one service and a relational database for another service. we can write one service in .Net and one service in Java if we really want to.
What I have also seen is that it’s easier to follow the single responsibility pattern and avoid ‘god’ objects. Developers sometimes tend to add things to existing component, leading to mega classes that are doing way too much. In microservices architecture, it is harder to do so because of that separation. you end up with smaller and simpler components which is great.
Independent Deployment:
We can deploy only parts of our system. We don’t need to wait for an entire feature to be complete.
It also means we can replace services very easily. if we found a bug in our Ordering system, we can just fix it and deploy it without the need to deploy the rest of our services.
We have more control about what, when and where to deploy. We might want to deploy different versions to different regions in the world.
Independent Scalability: services can be scaled independently of each other whenever there is a need like a really busy period (think about retail stores on black Friday for example)
Application agnostic: You can write a service that can be used by more than one team. For example; I wrote an Email Service that is responsible for sending emails. Now if the company has multiple products, they can all use that service.
Based on my personal experience, here are reason to not like microservice architecture:
Might be harder to develop locally:
You might need to have multiple IDEs or processes running locally in order to run a simple business scenario. that can slow things down and make it more complicated to debug.
harder to have good integration tests.
Could increase DevOps complexity: a good DevOps team should be ready to handle any amount of services, but easier said than done. The more moving parts you have, the more you’d need to communicate,synch and even monitor.
Adding complexity:
Version control can be hard to control, maintain and support.
May end up with complex spaghetti code: not good old spaghetti code, but a micro-service spaghetti code. What I mean is that you might have X amount of services calling other services. This could really be a problem without defined boundaries (where do we split services?).
Distributed Transactions and consistency across microservices: In a monolithic system, we have a database system to ensure ACIDity. So in a good old monolith, we can easily rollback the entire transaction if something failed. But in distribute systems it can very hard. One way to solve it is by having idempotent services but that’s not always an option. we sometimes must have success/fail state of the entire transaction. There are ways to deal with it, but it’s just adding more complexity when you compare it to a simple one transaction in a monolith system.
Final thought about microservice architecture :
Use it when it makes sense. Don’t just go with it because it’s a hot trend. some solutions might be fine with a decent size monolith.
If you choose to go with it, try to have defined boundaries. it can be hard and usually it’s a task for a senior team member that has some business knowledge. I have seen super small microservices that were really nano-services; so small that I could barely see the benefit of splitting them and the overhead was bigger than the benefit of having them.