There are many hurdles to overcome when launching scalable and maintainable products. Working together as a large team is one of the things that often introduces challenges.
We developers are very good at creating abstractions and processes to solve our problems. One of the solutions conceived to simplify, among other things, collaboration is the microservice architecture pattern.
The pattern doesn’t really need any introduction as it became popular among developers, architects, and managers very quickly, but the basic idea is that you break the project down into several small, loosely coupled projects that can be deployed and tested independently.
There are a number of benefits being ascribed to this approach:
- Projects with a single responsibility can be worked on in isolation, minimizing the risk of conflicting updates.
- Small purpose-specific projects are easy to deploy and test in isolation.
- Smaller independent services are easier to understand, reason about, and update.
- The ability to scale isolated parts of the system can lead to more efficient use of resources.
- Freedom to choose different technologies for each independent service.
Those are some pretty desirable qualities.
Note: Keep in mind that these qualities aren’t necessarily unique to microservices (e.g. monoliths can also have very strict module boundaries and achieve high cohesion and loose coupling, you can isolate parts of a system and use a different technology stack in a non-microservice architecture, most architectures allow you to test functionality in isolation and some lend themselves to holistic testing as well etc).
It is important to remember that when it comes to deciding upon architecture of a software system, there is no “silver bullet” — every architecture has a set of trade-offs. Microservice architecture is no exception and has its benefits, but also costs. We developers are not only good at creating solutions, we’re also very good at seeing nails everywhere when we know that hammers exist. And this post serves as a gentle reminder that you can never blindly apply an architecture to a project without carefully considering its unique properties.
Because the microservice pattern does come with its own set of challenges, it is imperative that we do not forget the fact that projects, and the circumstances within which they exist, are unique. Just because an architecture works really well in one project doesn’t mean that the results are reproducible and that it will work equally well in another, similar but different, project.
Applying the microservice pattern can be an awesome enabler, increase productivity and happiness, and turn your architecture into a marvel worthy of the books of history. It can also make your project unbearable to work with or delay a product launch indefinitely. It should not be considered a panacea.
Whether to design a monolith, a set of microservices, or something in-between is a decision that requires serious insight. You must carefully consider the benefits and drawbacks and how they realistically (!) align with the goals of the project and the conditions that apply. Finally, it is worth remembering that beyond purely technical considerations the decision of adopting microservices or not depends on many other factors, such as: project budget, skills and experience of developers, organizational structure, project duration, etc.