Cloud-based application development has come a long way thanks to capabilities such as continuous delivery, automation and virtualization, among others. But if you’re looking to optimize your application development even further, transitioning from a monolithic to a microservices architecture is worth considering.
While a monolithic application puts all of its functionality into a single process and scales by replicating on multiple servers, a microservices architecture breaks an application down into smaller applications, and then segments them by logical domains (e.g. authentication, user directory, reporting, checkout, etc.). Together, microservices communicate with one another over APIs to form what appears as a single application to end users.
Once companies reach a certain scale, creating one massive, monolithic application can become overwhelming. We reached this point at my company when we had about 300,000 lines of code and four different technical teams. Applications built on microservices are much easier to change and maintain. Rather than adjusting and re-releasing all 300,000 lines of code, microservices architecture can be refactored and redeployed much quicker, improving release time and limiting the impact of code breaks. If there’s a bug in a microservices architecture, finding and fixing it is easier because you know where the code resides (within its logical domain). In a monolithic architecture, finding a code break is like finding a needle in a haystack.
While it is no small feat to move from monolithic to microservices, the transition has proved enormously valuable. Here are the seven lessons we learned during the process:
Determine If This Transition Makes Sense for You
This is a crucial, initial question to ask. Does a move from monolithic to microservices address the challenges your company is having? Are the benefits clear? How many team members will the transition affect, and do they have the capacity and/or experience to orchestrate a move of this magnitude?
Get Organizational Buy-In and Build Advocacy
It’s important to explain to your technical teams and those affected why you’re making this move. Share as much information as you can about microservices, and discuss why your company is investing in the move. Also, be transparent about the work that will be involved. For some team members, the transition won’t affect them much, but for others, their world is going to be turned upside-down.
To establish support for the switch, I compiled a detailed document summarizing the history of our application, all in the framework of architectural stories. This helped me clearly outline the challenges we were having and explain why we wanted to invest in transitioning from monolithic to microservices. It was mandatory reading for all of our architects, and after receiving their feedback, I distributed it to the entire company. This document expedited getting buy-in from the executives at my company, which was crucial, given the scope and cost of the undertaking.
Solidify Boundaries, Define Responsibilities
It’s crucial to determine who on your team is going to own what tasks. Politically, this can sometimes be a challenge; however, once you break up the project into various parts and assign ownership to teams, the challenges will become clearer and your project to-do list will come into focus. Additionally, this encourages knowledge-sharing between individuals and teams.
I found it helpful to structure our teams so that everyone worked as full-stack developers, rather than specialists. This meant that everyone had to code against both our database and the front-end. Having full-stack developers provides more flexibility and limits major lulls of work among your team when their specialty isn’t needed. The reverse also is true, where there are few bottlenecks when you don’t have enough specialists when their needs are high.
While most companies start out with around five microservices, they’ll likely have upwards of 300 microservices in a short amount of time. Given this reality, it’s important to have automation in place early so that scaling microservices is feasible. Think about it: the more microservices you build, the more difficult it will become to configure all of its supporting needs manually (e.g. virtual machines, servers, and databases). The same goes for testing. You’ll need to automate all parts of the builds, tests, provisions and deployments.
Agree on a Communication Plan
Use consumer-driven contracts so that everyone is aware of the requirements of their code and distinct boundaries are clear. Make it a rule: For anyone who submits to APIs or changes anything, they need to meet these consumer-driven contracts. Doing so will make things less murky, especially when dealing with consultants or developers who work off-site, and it will prevent someone from making changes in one area and breaking something else as a result. Consumer-driven contracts can help speed up the build process and make the boundaries of microservices more distinct.
I also urge teams to communicate over APIs, rather than directly hitting someone’s database or sending a CSV file. This allows teams to be more independent, because APIs prevent teams from coupling to one another and provide flexible access to functionality and data to other teams.
Lastly, make sure there’s good inter-team communication, as well. Teams need to learn not only how to communicate over APIs, but also how to communicate effectively with each other.
Even though various parts of the page are served up from separate microservices, the user interface (UI) layer must appear as one cohesive page. By solving the problem of allowing teams to have microservices that can even interact as the UI layer, the teams don’t just build backend services and rely on a different team for the UI layer. Instead, the teams can work independently on the full stack, from the UI layer down to the backend.
Implement Security Between Microservices
You’ll need to establish a consistent way to monitor security between server-to-server microservice communications and session management. If all of your microservices are talking to each other without any security, security threats are akin to a kid in a candy store.
Our team created “autobots” (essentially faux API calls) to mimic microservice endpoints. Then we used those autobots to develop on desktops and perform automated regression tests. This allowed us to implement quality and security measures without having every single microservice running on each developer’s desktop or continuous build environment, which is too complex and costly.
Transitioning from a monolithic to a microservices architecture is a significant undertaking, but there are also significant benefits, like greater agility and efficiency. In order to be successful in such a move, remember to constantly communicate. Thoroughly research microservices and clearly explain how it will affect your company and technical teams. Make sure responsibilities, boundaries and project timelines are understood, and determine how your architects are going to work with one another. Lastly, don’t forget about automation and security, because a successful move from monolithic to microservices depends on scalability and the safety of your company.
David Hardwick is CTO of BetterCloud, where he coordinates an Atlanta-based team of sixty-five technologists. He is responsible for overall product development and operation.