The challenge
The client's fintech platform had a REST API with 120+ endpoints serving 3 frontend clients (web dashboard, mobile app, partner portal). Each client needed different data shapes, leading to massive over-fetching — the mobile app was downloading 4× the data it actually used. Adding new fields required backend changes, creating a bottleneck between frontend and backend teams.
Four engineering teams shared one monolithic API. Any change risked breaking other teams' integrations. Deploy frequency had dropped to once per week due to coordination overhead.
Our approach
We designed a federated GraphQL architecture with Apollo Federation v2. Instead of one massive schema, we split into 4 domain-specific subgraphs — Users, Payments, Invoices, and Analytics — each owned by one team. The Apollo Gateway composes them into a unified graph at runtime.
We ran the migration incrementally: REST and GraphQL ran side-by-side for 4 weeks. Shadow traffic testing caught 12 edge cases before full cutover. Frontend teams migrated their data layer using GraphQL Codegen for type-safe queries.
Key technical decisions:
- Apollo Federation v2 for team autonomy and independent deployments
- DataLoader for batching and deduplication (solved N+1 query issues)
- Chose NOT to use schema stitching — federation's ownership model was better for their team structure
- Redis query caching at the gateway level for frequently accessed data
What we built
A production federated GraphQL API serving 3 client applications:
- 4 independently deployable subgraphs with schema composition checks in CI
- Type-safe client SDKs auto-generated from the schema
- Query response caching reducing database load by 45%
- DataLoader batching eliminating N+1 queries across all resolvers
- Apollo Studio for query analytics, deprecation tracking, and schema changelog
- Comprehensive migration guide and REST deprecation timeline