The backbone of Sonata.ai
Before we even wrote a first line of the code of Sonata.ai, we have broken down the requirements of the platform into a list and analysed it. We also went through possibly all options of an architectural design. The lengthiest part of the discussion was choosing between the two main development techniques: monolithic and microservice-based architecture.
This article is as an extremely shortened version of an ongoing discussion of our backend developers. It is by no means intended as an exhaustive look at the theory of development patterns. Consider it a mere sum up for our tech-enthusiastic readers.
What are microservices?
First, it’s worth mentioning that microservices don’t solve all problems of monolithic system per se. Wrong usage of this development pattern can lead to the exact opposite of desired effect: cluttered and unsustainable code base. Every project has a few suitable solutions and although using microservices is often seen as the more advanced approach, they are no panacea.
With microservices, the final product becomes a set of numerous specialised services communicating via API. Ideally, every service is as simple as possible and completely autonomous. In practice, every service is running as a separate process, has its own resources, database and is developed independently.
Each one of the services can be written using a different programming language. There are less dependencies. Code is also easier to make sense of (in comparison to monolith). Thus, there is no problem to throw away a part of the platform and start again from scratch if there is later a critical error found in the design.
But everything comes with a price. It is somehow difficult to draw the line between each individual microservices. There is no universal agreement on how to divide processes of a platform. Also, a quite tricky part of communication between the services comes to play. Let’s break down the pros and cons of these two approaches.
Monolithic architecture vs. microservices
- Communication between individual components is simple
- Consistency of code
- Easier to refactor
- When updating, the whole application needs to be tested before deployment
- Scaling must be prepared for the whole instance — that usually requires more guess work and powerful hardware
- An error can lead to malfunction of the whole platform
- Complex development documentation is a must
- Easier continuous development — every part can be deployed individually
- Higher availability of the service
- No limit to used technologies
- Complex communication between services
- Distributed transactions
- The overall design needs a higher level of sophistication
- Necessity of high-quality monitoring
Why did we choose microservices?
Basic requirement for the platform was a 24/7 availability. Partly because we have witnessed frequent outages of other platforms ourselves and partly because this problem was among the most common complaints of our respondents. Our DevOps have prepared a set of tools to monitor utilisation of individual processes. Every service runs in a separate container. Thanks to microservices, we can on the fly increase computing capacity for a specific part of the system.
Sonata.ai is first and foremost meant to be a user-friendly platform. Our designers wanted to be able to react to a popular demand and needs of users. For this reason, ability to quickly deploy updated part of the service was a must. We are able to modify any part of the application in no time and without effectively affecting the user-experience. That is also why we have developed CI/CD infrastructure with zero-downtime deployment.
Our team of developers is not based in a single office, but rather scattered on different places. Based on our previous experience, we are using agile methodology. That is why we can avoid common mistakes and get things done quickly and effectively. Using microservices helps us to pick appropriate technological solution for every problem. We can also rewrite each part completely if we find it suboptimal. Hopefully, this won’t happen too often.