I wanna create a web service that can survive for 10 years without slowing down development speed.
In the past, I’ve seen several web services that are so-called “legacy” web services. I found that many of them started with well-designed layered-architectures. But as time went by, they lost their original idea and became complicated.
A few years ago, I was assigned to launch a new service. Then I wondered what I should do to avoid falling into the same trap. Should I think about how to create a perfect system from the beginning?
No. Only a system that can adapt to change can survive. But based on this idea, we need to control the risks of bugs caused by changes. How can we control them?
It seems good to break down a system into several small pieces. To do so, we can utilize DDD and Microservices. So this architecture seems good.
But should I start from here? No, we don’t need it at the beginning.
An Evolutionary Approach
That’s why I think it’s good to adapt an evolutionary approach. There are mainly 2 phases: the Boot phase and the Cloud phase.
Let’s start from the Boot phase with 5 to 7 team members.
The Boot Phase
First, we make a simple CRUD application with Spring Boot, message queue, and a database to launch our service as soon as possible.
Then, as we grow to better understand the business, the domain model will start to appear gradually. After refactoring the model and the code again and again, we will be able to make simple and condensed aggregates.
Each aggregate is loosely coupled with domain events. On the way to create aggregates, you will discover that you are free from the database because data-related logic will be separated into repositories.
Actually, my team is now in this stage. And we feel that UI related logic should be removed, too. For that purpose, CQRS might be a good choice. With CQRS, we can separate query logic from our domain model. Users can search data from the query model, and update data with the domain model.
Thanks to DDD and CQRS, we can create loosely coupled web application. This is the Boot phase. Until our service needs further expansion, I think it’s ok to stay here and keep refactoring it.
The Cloud Phase
So when do we need to move to Microservices?
If we can't feed a team with two pizzas, it’s time to move on to the Cloud phase. Before creating the actual microservices, we should prepare the environment for it. Let’s surround our application with Spring Cloud.
Spring Cloud provides many features which are common when building microservices. Examples include ConfigServer, DiscoveryServer, and so on.
When the team get used to the environment, it’s time to separate one aggregate as a microservice. It’s still ok to keep using the same message queue and database during this time.
After we find that it all works well, we will also separate the message queue and the database for the new microservice. Then the team will split into two and become loosely coupled to maintain good development speed, even though the service became bigger.
Finally, the system will be something like this.
I believe with this architecture, the system will be able to survive for 10 years while adapting to changes and speeding up the development.
To maximize the business value, an evolutionary approach is very useful. That is because it evolves along with both the business growth and the team’s growth. The most important thing when adopting an evolutionary approach is to draw paths in which our system can grow step by step.
I’m sure Spring Boot and Spring Cloud will give us the flexibility of these choices. That’s why I’m here. I would like to learn a lot about Spring Cloud and Microservices for our future growth.
ばふぁ節が炸裂してる！ pic.twitter.com/TKsyLhKxY4— Shin Tanimoto@Mystic (@cero_t) 2016年8月2日