Microservices are a very hot topic right now and the appearance of tools like Docker probably made a good contribution to that.
According to Wikipedia:
Microservices is a software architecture style in which complex applications are composed of small, independent processes communicating with each other using language-agnostic APIs. These services are small, highly decoupled and focus on doing a small task,facilitating modular approach to system-building.
Some of advantages of using a Microservice oriented Architecture are:
- Smaller and easy to understand code base, since each service focus only on one functionality.
- Separation of concerns. Different teams can work on different components in a more isolated way.
- Easier to scale. With a large, monolithic application you have to scale your application together but with a Microservice oriented architecture you can scale your components separately.
- Each component can use a completely different technology stack making possible to use the best tools and languages for the job, instead of one size fit’s all approach.
- System resilience - If one service fails, the rest of your system should continue working. (In practice, it might be not that simple).
But all this comes with a cost The system becomes more complex to manage. In a medium sized project you can easily get dozens of Microservices. Making sure than all of them work together in harmony is not a simple task. The required DevOps work is much bigger. Check this article for a more detailed explanation of the pros and cons of Microservices.
So you are starting a new project, you maybe be thinking, should I start it with a Microservice based architecture? In most cases no. Its premature optimization. The most important thing in the early ages of a new project is to get your MVP ready as soon as possible to get feedback from customers. Be pragmatic and focus on your product.
Monolithic apps doesn´t mean messy code. When building your application, think about the main components of it and the ones that are more likely to change in the future, in both functional and non functional requirements (scaling, tech stack etc). Make then decoupled from each other. Apply the SOLID principles and other design patterns. For Example, if your building a social network app, the logic for building the newsfeed should be an independent from the logic that runs the chat, or the notifications system. If you build your application with that in mind, when your application grows and you find the need to extract that component into separate service it will be much easier.
Florian Motlik, CTO from Codeship wrote a very interesting article about this topic. The ideas behind this post. is similar to what he calls "Microservice architecture with a monolithic core".
I believe thats the way to go in most cases. Of course every application is different, so do what you think its best for your case.