For the past couple of years, microservices have been a hot topic of conversation in the field of information technology. The hype around microservices is that they make everything better, and as an engineer who works on an application, I’m an enthusiastic promoter of the philosophy.
When properly implemented, a microservices architecture offers many benefits. However, this approach isn’t right for every organization or application. In this article, we’re going to look at microservices in more depth, and discuss how you can use an API-based approach to implement and manage them. We’ll also discuss the advantages of this approach, and some of the reasons why you should or shouldn’t consider microservices.
What are microservices?
The philosophy behind microservices is that your application is composed of a collection of units, each of which provides the functionality for a single business task. An example helps to illustrate this process, so let’s consider how you might put together the payment portal for an e-commerce application. In a monolithic application, payment operations are part of the application itself, but for microservices, we’ll break these out into a distinct payment domain and then break them out further into microservices for different operations.
Figure 1. Comparing payment functionality in a monolithic application vs. a microservices approach
If we look at the functionality to handle PayPal transactions in the two application architectures above, you’ll see that the PayPal code is embedded directly within the monolithic application. In the microservices approach, there is a separate PayPal service. This PayPal service exists as an independent application and is designed, written, deployed and maintained as such. When another part of the “application” needs to access PayPal functionality, it interacts directly with this service.
A benefit to this approach is that if the interaction with PayPal needs to change, then only the PayPal service needs to be updated and deployed, instead of the entire application. There are some steps you’ll need to take to ensure that this update of a single piece of functionality takes place flawlessly, and we’ll discuss that next.
Microservices and APIs
Microservices typically exist as web services with a REST, SOAP or other API implemented to allow other services to communicate with them. An application programming interface (API) is a contract between the service and its clients. Documenting the API before the development of the service allows client services to understand how to interact with the service. This documentation allows client services to create virtual versions of the PayPal service and create integration tests without relying on the full implementation of the PayPal service to be complete. This approach is known as API-First development.
An additional advantage of having an API is that you can update the internal workings of your service, and as long as the service still meets the specifications of the API contract, the client services won’t be affected by any updates.
Figure 2. Updating the service behind an API
As long as version 1.1 of the PayPal service still meets the specifications of the API, we can replace it in our environment without affecting our clients. We’ll examine how to implement more extensive updates next.
The benefits of using microservices
Since change is a constant in our industry, we need a strategy to handle more extensive updates, including updates to our API contracts. These changes can be implemented using API versioning. When updates require changes to the API, we first design and publish a new version of the API. The new service implementing this updated API is deployed together with the original version. This approach allows client services to update when they are ready, and immediately begin accessing the new version.
Figure 3. API versioning to introduce major changes to a service
Thus, microservices are a good architectural strategy for applications that need to be updated frequently, and that can communicate using APIs. This describes most applications today. After all, we're living in an age of "cloud-native" computing and "continuous everything." Users have grown accustomed to applications that are hosted in the cloud and are continuously updated. Microservices are a good solution for building these types of applications.
When microservices aren’t the answer
That said, microservices aren't always the best architectural solution for your application.
As much as I believe in the power of microservices and the advantages that a microservices architecture provides to an application, there are reasons you might want to consider staying with a monolithic application. Adopting a microservices architecture requires a substantial investment of both time and money. If your organization doesn’t fully understand how a microservices architecture works, you are better off sticking with your existing monolithic application.
Among the other popular justifications for adopting a microservice architecture is that systems that use this approach can be faster and are easier to scale up for increased traffic. That’s true, but keep in mind that microservices aren’t the only way to achieve these ends. Both of these problems can also be solved within a monolithic application with careful design and disciplined engineering practices. Whether it’s easier to achieve the desired results in this respect using microservices or by sticking with your monolith depends on how experienced your team is with microservices, and how much effort it would take to overhaul your monolith.
In a perfect world, every monolith would be transformed into a microservices-based app. But in the real world, we have to make strategic decisions about which apps we actually overhaul in this way.
Splitting the difference: a hybrid microservices approach
Now that I've told you when to use microservices and when not to, let me also state that microservices aren't necessarily and either/or proposition. If you believe that your application is a good fit for a microservices architecture, but you do not yet have the resources available to convert your monolith wholesale to microservices, you can take a hybrid approach.
That approach entails converting some parts of the application to microservices, while retaining the rest of the application as a monolithic codebase. For example, you might want to convert those components of your application that are most frequently updated to microservices, even if the rest of the application remains monolithic. This hybrid approach can make it easier to take advantage of microservices in conjunction with a legacy application even if your development resources are limited.
Resources to learn more
If you would like to learn more about microservices and best practices for designing and implementing a microservices platform, I would recommend Martin Fowler’s writings on the topic. An online presentation on microservice testing within those materials offers excellent information on best practices.