A project to break a monolithic application down into smaller microservices is different from the “standard” software development project. Because of this, microservices projects have different phases and need to be run differently.
When I mention a “standard” software development project above, I’m referring to creating a new application or adding features to an existing project. With microservices, you are migrating features and functionality from one application to another, while ensuring that they are integrated efficiently.
In a previous post we talked about getting started with microservices and here we’ll dive into the project phases we follow at Headspring, along with a few closing thoughts and lessons learned from our experience in moving from a monolith to microservices.
Define Business Boundaries
The first phase of the project is to determine the different possible combinations of feature sets to combine into a microservice. We work hand-in-hand with our clients to define business boundaries (or bounded contexts), and those boundaries are typically perfect candidates for microservices.
Here’s a look at the process to define business boundaries:
- Knowledge Transfer: The best way to define business boundaries is to understand as much as possible about the application and the user workflows within the application.
- Hands-on Learning: Our teams gain access to a non-prod instance of the application and learn as much as possible by using the application.
- Interview: We interview the product owners to get an understanding of the following:
- What are the different sections of the application?
- Who are the different types of users of the application?
- What are the workflows that each type of user typically takes to complete a function?
- What is the feature roadmap for each of the sections of the application?
- Are there feature-sets that can be purchased/enabled separately?
- Create: With this information, we create a first pass at the business boundaries and put together a visual map of these boundaries.
- Revise: Finally, we review the business boundaries map with the product owners and technical leads to incorporate any feedback that they have.
Select a Business Boundary for the First Microservice
Once the business boundaries have been established, the next step is to work with the organization to determine which business boundary to break out into the first microservice.
Consider the following factors when selecting the first business boundary:
- Feature Roadmap: It is better to start with a service that doesn’t have a lot of critical, near-term features planned on the roadmap. To prevent additional re-work and code migration, slow down or stop new feature development in the area of the service you’re going to break out.
- Team Size: Generally, it is difficult to keep a large team of developers busy at the beginning of standing up a new microservice, especially if they are junior developers.
- Performance Issues: If there is a boundary that is having performance problems, it could make a good candidate for the first service. Once the microservice is developed and running on its own server, then additional hardware can be added to that server to get performance improvements.
- Complexity: It is better to start with a less complex service in the beginning, to allow patterns to be established correctly. Some of these patterns will be:
- CI/CD pipeline
- Testing strategy
- Production deployment process
- UI integration strategy
Create the Development Backlog
Once there is agreement on the first microservice, we are ready to ramp the development team up.
Creating the initial development backlog is one of the areas that is different from “standard” software development projects. Typically, it’s the product owners working with the technical leads to create the backlog since they know the features that need to be implemented. For microservices projects, the team already knows the features that need to be implemented, so the backlog is more technical and consists of technical tasks to break dependencies by migrating code from the monolith to the microservice.
To create the initial backlog, we follow these steps:
- Analyze the boundary for dependencies with other parts of the application. We need to understand all of the parts of the application that need to be broken out into a new service.
- Dive deeper into each of the dependencies that were identified in the first step.
- If it’s straightforward to break the dependency, then create a ticket with the details
- If it requires a lot of investigation to determine how the dependency should be broken, then create detailed research tasks
- Once we create the initial backlog with a combination of simple development tickets and research tasks, the team is ready to start doing the work.
- Assign the simpler tickets to the junior developers in sprint 1
- Assign the research tasks to the senior developers and leads in sprint 1, with the goal of the tasks being to create additional development tickets with additional details on how to break the dependencies
Develop and Test the Microservice
After the tech lead has an understanding of the backlog of features that will need to be migrated, we typically create a proposed architecture based on the needs of the service. This architecture is subject to change as the development work continues, but it’s good for the team to have an understanding of the proposed architecture and the reasoning behind each of the architectural components such as messaging.
This is another part of the project that is different from your “standard” software development. Each completed individual development task might not be testable by a QA team member. In some cases, it’s not until the majority of the backlog is completed that the new microservice can be tested end-to-end.
It’s very important to have a solid regression test plan, since the goal of the microservice is to have feature parity. We usually have the QA team focused on developing or enhancing the regression test plan while development is ongoing, so that they will be able to ensure that the new service is working correctly when the development work is complete.
Deploy the Microservice
We like to develop our microservice behind a feature flag whenever possible, to reduce the risk of deployment to production. This allows us to deployment the microservice and the changes to the main application to support the microservice, but with the microservice turned off and not in use.
Then, we turn on the microservice feature flag in production and ensure that it is behaving correctly. If there are any issues, we can simply turn the feature flag off and the original application will function exactly as it was before. We develop our microservices in a way that this rollback will always be achievable.
- Microservices projects are never the same. It doesn’t matter how much experience you have, there are always aspects of each project that are very unique to the situation.
- Microservices are strategic initiatives that take time to implement correctly.
- One thing that microservices projects have in common with standard projects is that there will be must-have and nice-to-have features that need to be prioritized throughout the project. The creation of the “picture perfect” service is different from the creation of a service that is serviceable and ready to be used in production.