THE MIGRATION LINE
INCIDENT // AGODA-2024IN PROGRESS

Agoda's GraphQL API had backed every client app since 2016. To split it into microservices without breaking any of the 70 clients depending on it, they migrated the clients before they touched the backend.

AGODA·2024·GRAPHQL / MICROSERVICES / MIGRATION-STRATEGY / INFRA·✓ Sourced — medium.com
System stress over timeNominal
70Clients served
3 of 7Microservices shipped
~100Repos audited
since 2016Monolith age
BASELINE

One GraphQL service, seventy clients, eight years of accretion

Since 2016, Agoda has run a single monolithic GraphQL API as the backend for its Hotel Management application and everything built on top of it — eventually 70 client applications, all reading and writing through the same schema. As new business domains arrived, their backend logic landed in the same codebase, because that’s where everything else already lived.

It worked, for a while. But a service that backs 70 clients accumulates more than features — it accumulates coupling.

REQUIREMENTS

Whatever replaces it has to be invisible to 70 client teams

The target was six logical microservices, split along business-capability and data-ownership lines. But the real constraint wasn’t the split — it was who had to feel it. Agoda needed a way to move traffic domain by domain without asking any of the 70 client teams to change a line of code, because a migration that requires 70 coordinated client releases is really 70 migrations, not one.

OPTIONS

Apollo Federation assumes the microservices already exist

The obvious first candidate was Apollo Federation, the standard way to compose a GraphQL schema out of multiple services. Agoda evaluated it and ruled it out: Federation “works best with existing microservices,” not with the gradual decomposition of a monolith that’s still mostly whole. Adopting it would have meant standing up all the target services before having any safe way to cut traffic over to them — backwards from the incremental, low-risk migration Agoda actually needed.

DECISION

Smart Orchestrator: a routing table with no business logic

Instead, Agoda built the Smart Orchestrator — a custom client library whose only job is routing. It queries each domain’s schema through introspection, folds the results into an in-memory Microservice Mapping Table, and uses that table to send each incoming request to whichever service currently owns it — monolith or microservice, transparently. Because it holds no business logic of its own, it can be pointed at a new backend the moment that backend is ready, without a redeploy on the client side.

RESULTS

Three of seven, and zero client-side code changes

To find the real domain boundaries, Agoda ran ETL jobs over production GraphQL traffic from all 70 clients and classified every query as Simple, Moderate, or Complex based on how many domains it stitched together — because a query touching three domains can’t move until all three are ready. That analysis is what surfaced the roughly 100 repositories carrying stitched queries in the first place.

By the time of writing, three of the seven planned microservices had been transitioned this way. Agoda’s own framing: “we had to do zero code change on the client side to move traffic extracted to the microservice.”

A migration that starts with the clients instead of the servers buys you invisible cutovers — the backend changes underneath, and none of the 70 apps calling it ever have to know when.

Source — read the original

A plain-language, AI-drafted and human-edited retelling of the article published on medium.com, reorganized and explained in our own structure and words, with original analysis in the editor's note above. The facts, numbers, and decisions belong to the original author and are not altered. For the full depth, read the source.

← All systems