The Call for Code 2019 Global Challenge is now open for submissions. Learn more
by Kyle Brown | Published February 13, 2017
If you’re like me, you’re constantly reading articles and blogs about new development tools, new development and operations practices, or new architectural principles. The problem is that too often, these practices or architectural principles might look great on paper, or perhaps would work out fine if you were to implement them in a brand new (greenfield) application, but it’s not quite as clear how you would implement them in an existing application.
However, we live in a world where brownfield applications—existing apps that were not built according to all the latest approaches, or using the latest tools—are more common. This is particularly true of the microservices architecture. Most of the development teams I talk to think microservices sound like a great idea, but they’re not sure how they can start using them since they are currently working with huge monolithic applications.
Thus, it’s great when you come across a solution that’s really helpful in situations like this, and that’s true of Martin Fowler’s Strangler Application pattern. And even though he wrote it prior to the development of the microservices architecture, this pattern offers excellent guidance to teams that want to move to a microservices approach.
In a 2004 article on his website, Martin Fowler defined the Strangler Application pattern as a way of handling the release of refactored code in a large web application.
The Strangler Application is based on an analogy to a vine that strangles a tree that it’s wrapped around. The idea is that you use the structure of a web application—the fact that web apps are built out of individual URIs that map functionally to different aspects of a business domain—to divide an application into different functional domains, and replace those domains with a new microservices-based implementation one domain at a time. This creates two separate applications that live side by side in the same URI space. Over time, the newly refactored application “strangles” or replaces the original application until finally you can shut off the monolithic application. Thus, the Strangler Application steps are transform, coexist, and eliminate:
The great thing about applying this pattern is that it creates incremental value in a much faster timeframe than if you tried a “big bang” migration in which you update all the code of your application before you release any of the new functionality. It also gives you an incremental approach for adopting microservices—one where, if you find that the approach doesn’t work in your environment, you have a simple way to change direction if needed.
Of course, you can’t assume that a pattern will apply to every situation. There are a few prerequisites that must be in place in order for this approach to be successful:
Just as there are cases where the pattern applies, there are likewise cases where it does not apply—or at least does not apply easily. These cases include:
You have to interleave two different aspects of your application refactoring: refactoring your back end to the microservices design (the inside part), and refactoring your front end to accommodate the microservices and to make any new functional changes that are driving the refactoring (the outside part).
The process of planning out the application of the Strangler Application pattern in the middle of a brownfield project is often complicated by the fact that you’re not only changing your back-end implementation to incorporate microservices, but there are usually lots of front-end UI changes happening as part of the project as well. In fact, it’s often the front-end changes (for instance, implementing a site as a single-page application or a mobile application) that drives the desire to implement microservices in the first place. With a microservices architecture, you can’t assume that you know exactly how the UI design is going to turn out, or exactly what changes the UI team are going to implement a priori. But you can make some simple assumptions that can help you get started with your design:
In the IBM Cloud Garage Method, we use certain concepts from Agile methods to help us organize our work. For instance, a Hill (or an MVP definition) is broken down through the inception process into User Stories that represent individual implementable elements of the MVP. Related User Stories are grouped into Epics that describe higher levels of system functionality.
That brings us back to the challenge of gradual system replacement through the Strangler Application pattern. Epics are grouped together into Chunks, which are tied together either by implementation restrictions or user-experience relationships that become initial large-scale rollout units. In most cases, a Chunk is bounded by a UI flow that defines a user task, and all the parts within that flow are implemented in a consistent way.
Squads implement Epics: A single Squad may implement one or more Epics within a Chunk, but the smallest element of implementation responsibility for a Squad is an Epic. The Squad adds the User Stories that define that Epic to an ongoing Ranked Backlog of prioritized User Stories for implementation.
However, a Chunk is still a pretty big rollout unit when you’re trying to receive intermediate feedback from a set of sponsor users. Therefore, we define a smaller release element that can be used internally to gain that feedback. A Sliver is the smallest releasable unit that incorporates a microservice and the changes that surround the microservice to make it usable to the end user. So even though a chunk may be an entire flow for booking a ticket on a bus or an airplane and all of the microservices needed to implement that flow, a Sliver may be a single page within that flow that represents a step such as showing the confirmation of the ticket booking, plus the microservice needed to retrieve that confirmation. So your Chunk would be made up of Slivers that are continuously released and made available in a limited way for feedback, but only released to the end user when the entire task represented by the Chunk is workable.
In this article, I’ve shown you a few of the ramifications of applying the Strangler Application pattern—when it applies, when it doesn’t, and what it means for release management. I’ve also introduced a couple of new terms that we use in our consulting practice in the IBM Cloud Garage and that I hope you will find helpful. In particular, I’ve spotlighted a process for planning our your microservices development when applying the Strangler Application, and for managing the releases of functionality in your application.
April 15, 2019
This learning path is comprised of basic to advanced Kubernetes skills.
March 8, 2019
Back to top