Federation, Stitching and BFF: Which Architecture When?
AI generated
{ }
type
GraphQL · Federation · Stitching · BFF · Architecture
Federation, Stitching and BFF
Which Architecture When?

Apollo Federation v2, schema stitching and the Backend for Frontend pattern all solve the same underlying problem: coordinating distributed GraphQL data access. Which pattern fits when depends on team size, ownership boundaries and runtime requirements.

16 min read Federation v2 · Stitching · BFF · Gateway · Subgraph Apollo · Magento · Headless Commerce

1. The shared problem: coordinating multiple GraphQL sources

If you run a single GraphQL schema maintained by one team, you need neither Federation nor stitching nor a BFF. These patterns arise from a concrete problem: multiple teams maintain separate services, each service has its own GraphQL API, and the frontend still needs to talk to a single endpoint. The three architecture patterns, Federation, stitching and BFF, solve this problem in different ways, with different trade-offs in complexity, ownership and runtime behavior.

In an e-commerce context this problem is particularly pronounced: product data comes from Magento, customer preferences from a CRM, reviews from a dedicated review service, stock levels from a WMS. The frontend needs data from all of these sources at once, ideally in a single request. Three requests from the browser to three different endpoints are not a solution, because they add up network latency and push coordination logic into the frontend.

2. Apollo Federation v2: a distributed schema with clear ownership

Apollo Federation is a standard for distributed GraphQL schemas in which each service (subgraph) owns part of the overall schema. A central router, the gateway, receives queries, breaks them down into sub-queries for the relevant subgraphs, merges the results and returns a single response. The key to Federation is the @key directive: it lets a subgraph reference entities from other subgraphs without having to import their entire schema.

Federation is a good fit when clear team ownership boundaries exist: team A owns the product subgraph, team B owns the customer subgraph. Each team can evolve its schema independently, as long as the declared entities and keys remain stable. The router knows the composed schema and plans query execution automatically. That is powerful, but also complex: Federation v2 with Apollo Router comes with its own concepts such as shareable fields, override directives and the query planner, which you need to understand before using it in production.


# Product subgraph (Magento or dedicated catalog service)
extend schema
  @link(url: "https://specs.apollo.dev/federation/v2.3",
        import: ["@key", "@shareable"])

type Product @key(fields: "sku") {
  sku: String!
  name: String!
  price: Float!
}

type Query {
  product(sku: String!): Product
  products(search: String, pageSize: Int = 20): [Product!]!
}

# Review subgraph (separate service)
# extends Product from catalog subgraph
extend schema
  @link(url: "https://specs.apollo.dev/federation/v2.3",
        import: ["@key", "@external", "@requires"])

type Product @key(fields: "sku") {
  sku: String! @external
  reviews: [Review!]!
}

type Review {
  id: ID!
  rating: Int!
  comment: String
}

3. Schema stitching: pragmatic but complex

Schema stitching is the older approach: multiple GraphQL schemas are programmatically assembled into a single one. Unlike Federation there is no formal standard, the composition happens in code, typically in Node.js using tools such as GraphQL Tools or The Guild's @graphql-tools/stitch. That makes stitching more pragmatic and quicker to set up than Federation, but also more prone to unexpected interactions when merging types from different sources.

Stitching is a good fit for situations where you need to merge several existing GraphQL APIs quickly, without being able to change the individual services. It suits smaller teams or internal platforms where ownership boundaries are less sharply drawn. The price is higher maintenance complexity in the stitching layer itself: type conflicts, schema evolution and caching are harder to control than in a Federation setup with a formal schema registry.

4. Backend for Frontend: a purpose-built API layer

The Backend for Frontend pattern (BFF) is not a GraphQL-specific concept, but it fits GraphQL very well: for each frontend, web app, mobile app, kiosk, a dedicated API layer is built that delivers exactly the data that frontend needs. In a GraphQL BFF, that means a dedicated GraphQL schema exposing only the fields relevant to that particular frontend, with resolvers that aggregate data from various backend services.

A BFF is not an alternative to Federation or stitching, but a complementary layer: the BFF can itself be a subgraph of a federation, or use schema stitching internally. The advantage of a BFF is maximum freedom in API design: the frontend team can shape its schema exactly as it fits the frontend, without having to consider the structure of the backend services. The downside: with multiple frontends you quickly end up with a zoo of BFFs, each developing its own business logic and hard to coordinate.


# BFF schema: optimized for the web storefront's homepage
# Aggregates data from catalog, promotions and recommendation services
type HomepageData {
  hero_banner: HeroBanner
  featured_products: [FeaturedProduct!]!
  active_promotions: [Promotion!]!
  personalized_recommendations: [ProductRecommendation!]!
}

type FeaturedProduct {
  sku: String!
  name: String!
  image_url: String!
  price: Float!
  discount_percentage: Float
}

type HeroBanner {
  headline: String!
  subheadline: String
  cta_label: String!
  cta_url: String!
  background_image_url: String!
}

type Query {
  homepage: HomepageData!
    @resolver(class: "BFF\\Web\\Resolver\\Homepage")
}

5. Decision framework: which pattern fits when

The choice between Federation, stitching and BFF depends on three factors: team size and ownership structure, runtime requirements and change frequency, and the existing technology stack. Federation requires teams to be willing to structure their services according to Federation standards, with @key directives, entity definitions and a schema registry. That is an investment that only pays off from a certain team size and system complexity onward.

Stitching is the fastest solution for merging several existing APIs without being able to change the services. It is not, however, a long-term architecture for large teams, because the central stitching layer can become a bottleneck and a black box. A BFF is the right choice when a frontend team needs to move quickly and independently, without waiting for backend service changes, even at the cost of possible logic duplication across multiple BFFs.

6. Gateway concepts and runtime requirements

The router or gateway in a federation is critical infrastructure: it receives all queries, plans execution across subgraphs, sends sub-queries and merges results. Apollo Router (implemented in Rust) is currently the most performant option for Apollo Federation. For smaller setups, Apollo Gateway (Node.js) is sufficient. Both have different caching, authentication and rate-limiting concepts that can be configured in the gateway, independent of the subgraphs.

Runtime requirements for Federation are higher than for a single GraphQL API: the gateway must be highly available, because it is a single point of failure for all frontends. Schema updates in subgraphs must be compatible before they are deployed, which is why schema registry workflows with breaking-change detection exist. These operational requirements are a frequently underestimated cost when getting started with Federation.

7. Magento as a subgraph in a federation

Magento can be integrated as a subgraph in an Apollo Federation, but not natively: Magento GraphQL does not support Federation directives out of the box. The solution is a thin proxy subgraph that exposes the Magento GraphQL schema externally while adding Federation-compatible @key directives. This proxy can be implemented in Node.js or PHP and translates between Magento's native GraphQL API and the Federation standard.

The more practical approach for most projects: Magento remains a standalone GraphQL endpoint, and a BFF layer aggregates Magento data with data from other sources. This pattern is simpler to operate and avoids the complexity of a full Federation setup, at the cost of a less formal separation of ownership. For pure headless commerce projects with a single frontend team, the BFF pattern is usually the more pragmatic choice.


# Thin federation-compatible proxy for Magento GraphQL
# Adds @key directives to make Magento types federation-aware
extend schema
  @link(url: "https://specs.apollo.dev/federation/v2.3",
        import: ["@key"])

# Magento Product type exposed as federation entity
type MagentoProduct @key(fields: "sku") {
  sku: String!
  name: String!
  price_range: PriceRange!
  categories: [Category!]!
}

type PriceRange {
  minimum_price: Price!
  maximum_price: Price!
}

type Price {
  final_price: Money!
  regular_price: Money!
}

type Money {
  value: Float!
  currency: String!
}

type Query {
  magentoProduct(sku: String!): MagentoProduct
  magentoProducts(search: String, pageSize: Int = 20): [MagentoProduct!]!
}

8. Common pitfalls across all three patterns

With Federation, the most common pitfall is the unreflective use of @extends for entities that should actually be @key entities with @external fields. Federation v2 has simplified these concepts, but the learning curve is steep. A second pitfall is missing schema registration before deploy: whoever changes subgraph schemas without validating them against the router's composition check risks a gateway failure that hits all frontends at once.

With stitching, the most common problem is the silent overwriting of fields: if two schemas define a type with the same name but different fields, one of the schemas wins depending on configuration and the other's fields are silently dropped. With BFF, the most common problem is business logic duplication: each BFF reimplements the same validation rules, which leads to inconsistencies between frontends whenever the rules change.

9. Summary

Federation, stitching and BFF are not competing standards, but complementary tools for different situations. Federation is the right choice for large platforms with several autonomous teams and clear service ownership boundaries. Stitching fits fast integration of existing APIs without changing services. The BFF pattern is optimal for fast, frontend-centric development, where a dedicated team should fully control the API layer.

The most important takeaway: all three patterns increase system complexity compared to a single GraphQL endpoint. That complexity is justified when the underlying problems, distributed teams, separate services, differing frontend requirements, are real and lasting. Whoever adds complexity before the problem is real pays the price without getting the benefit.

Federation, Stitching and BFF: The Essentials at a Glance

Federation

For large platforms with autonomous teams. Formal standard, schema registry, gateway as critical infrastructure. High complexity, high scalability.

Stitching

Pragmatic integration of existing APIs without service changes. Quick to get started, but higher maintenance risk as complexity grows.

BFF

Purpose-built API layer for a specific frontend. Maximum freedom, risk of logic duplication across multiple frontends.

Magento

Not natively a Federation subgraph. A proxy approach or a BFF is more pragmatic. A standalone endpoint often remains the simplest solution.

10. Head to head: Federation vs. Stitching vs. BFF

Criterion Federation Stitching BFF
Ownership Team per subgraph Central stitching team Frontend team
Complexity High (gateway, registry) Medium Low to medium
Scalability Very high Medium Per frontend
Entry barrier High Medium Low
Magento integration Proxy required Directly possible Directly possible

11. FAQ: Federation, Stitching and BFF

1From what team size does Federation pay off?
As a rule of thumb: from three or more teams with independent service ownership. Smaller teams benefit more from a BFF or a single API.
2Magento natively as a Federation subgraph?
No. Federation directives are not natively supported. A proxy subgraph with @key directives is the usual solution.
3Federation v1 vs. v2?
v2 simplifies type definitions, introduces @shareable and enables override directives for gradual migrations. No more need for @extends.
4When is stitching better than Federation?
When existing services cannot be changed, the team structure does not support subgraph ownership, or the timeframe is too tight.
5BFF with multiple parallel frontends?
Each frontend has its own BFF. Increases flexibility, carries risk of logic duplication. Move shared rules into backend services, not into the BFFs.
6What is a schema registry?
Stores all subgraph schemas and validates compatibility before deploy. Practically mandatory for Federation, without a registry you risk gateway failures after every subgraph update.
7Is BFF possible without GraphQL?
Yes. BFF is not a GraphQL concept. REST BFFs are equally common. GraphQL fits well because the frontend can choose the fields it needs itself.
8N+1 across subgraph boundaries?
The Federation router automatically batches reference lookups into a single _entities query to the affected subgraph. No manual batch loader needed.
9Which gateway for Apollo Federation?
Apollo Router (Rust) for high load. Apollo Gateway (Node.js) for smaller setups or when Node.js extensions are needed. Both production ready.
10Subgraph down during a query?
The gateway returns errors for the affected fields in the errors array. No automatic fallback. Circuit breaker logic in the gateway or subgraph must be implemented manually.