The Anti-Corruption Layer — Making Modernization Work

By Kiruthika Sivaraman, Software Engineer

StubHub
StubHub Product & Tech Blog

--

The process of modernization often results in the formation of two distinct worlds: the original, established platform and the new, more effective one. This is not a “one-and-done” process. Instead, it requires a series of phases over time. Because of this, the new world has a constant, ongoing dependency on the old one. Until all operations are fully migrated, the new world needs to have its own integrity but must also be compatible with legacy systems.

As StubHub continues its migration into the cloud, parts of our legacy system remain instrumental in fulfilling our essential day-to-day operations like customer orders.

Creating an intermediary layer — or an Anti-Corruption Layer (ACL) — between the new and old systems is a solution that gives developers flexibility and doesn’t come at the expense of performance.

Keeping the Checkout System in Check

Traditionally, the checkout application interacted with nearly all of the key components in the StubHub ecosystem. Naturally, being the most complicated system, we couldn’t get the migration done for the checkout in its entirety in one go.

Let’s say a customer is about to purchase a ticket using our old system. While on the checkout page, when the customer clicks the “Buy Now” button, we have the following series of events happening in background:

  1. We make a call to “Order Service” API which qualifies if user can complete the transaction
  2. If user is qualified, we call “Create Order” service to create the order
  3. If order creation is successful, the user then gets the success message with her order ID.

As a first step in modernization, we decided to move only the qualifying service (“Order Service”) to the cloud. But we still needed to make a call to the existing “Create Order” service.

We realized that as we gradually added more transitive dependent data to the “Create Order” service request, it made the service bloated. This polluted our “Order Service” function as it had to make calls to a bunch of different APIs to aggregate the data to send to the “Create Order” service.

Given that, we decided that we did not want that same overloaded “Order Service” API to be migrated into the cloud. So, we re-designed the “Order Service” API during our migration process to send only the minimum data required to the downstream system. By doing so, the new “Order Service” (referred to as “Order Microservice” in the below diagram) and the “Create Order” service were no longer compatible. We created the ACL to communicate between these two services.

In this new system, when a user clicks on the “Buy Now” button, it kicks off a series of steps:

  1. We call the qualifying service, the “Order Microservice,” in the cloud
  2. If the user is qualified, we send a success response to user with their order ID
  3. Simultaneously, we also trigger a process in the back end to create an order in the legacy system by dropping a message in the “message bus”

In the cloud, the “ACL Listener” (the dotted line in the diagram above) will receive this message and will call on the “Create Order Wrapper,” which is the ACL we designed in the legacy system. The “Create Order Wrapper” is responsible for retrieving the missing attributes required by the “Create Order Service.”

We chose to do these ACL tasks asynchronously as a benefit to the user, sparing him/her from experiencing the latency involved in introducing these additional layers. As all pre-checks are already completed by the “Order Microservice,” the only potential setback we might encounter is network failure (and since this isn’t the user’s fault, it’s only fair to let the customer complete her transaction as we work to fix any glitch in the background).

Now, if the ACL layer wasn’t there, we would have ended up with the same overloaded “Order Service” in the cloud. By introducing the ACL, we were able to improve the performance of “Order Microservice” by eliminating unwanted API calls and pushing all the heavy work to the ACL, which will happen asynchronously and not affect the user.

Right now, the ACL is not intended to be a permanent feature. When we migrate the “Create Order” service to the cloud, we will work on redesigning this API itself to take only a minimum of data in the request. By doing that, we will eliminate the need for the ACL.

In our case, if the ACL were to become a permanent solution, it would only complicate the overall system as it will work to maintain three components — the legacy system, the cloud and the ACL itself — instead of two. Instead, it is a layer that gives us flexibility to maintain the purity of the new system without compromising the customer experience. That being said, there can be use cases where we need ACL permanently. So, we need to be conscious of the role of ACL so we can design it effectively.

The 30,000 foot-view is that we are in a period of modernization at StubHub. And it’s an exciting time. These kinds of back end modifications are critical to unite the old systems with the new without impacting the customer journey in any way. We’re doing this in service of our customer to make sure that their experience at StubHub is as seamless and swift as it’s always been — and will continue to be.

Learn more about the author of this post, Kiruthika Sivaraman. Passionate about helping us with our modernization journey? Interested in bridging legacy systems with the future? Join us.

--

--

StubHub
StubHub Product & Tech Blog

Building better fan experiences. Product-focused, tech-driven, business-minded.