Federation (6 Questions)
Duration: ~15 minutes | Difficulty: Advanced | Prerequisites: Security (7 Questions)
Federation is the advanced topic that appears in interviews for senior roles at companies that have moved past the GraphQL monolith. If the job description mentions "supergraph," "subgraph," or "distributed GraphQL," expect federation questions. The questions in this chapter test whether you understand not just the mechanics but the organizational and architectural reasons federation exists.
Question 1: What problem does Apollo Federation solve, and when do you NOT need it?
Short answer: Federation allows multiple independent GraphQL services (subgraphs) to expose parts of a unified schema that clients query as if it were a single API. It solves the organizational problem of scaling GraphQL ownership across many teams without requiring them to take code dependencies on each other. You do not need it when a single team owns the entire GraphQL API, or when the overhead of a router, composition, and subgraph coordination exceeds the coordination cost it was meant to reduce.
Why this is right / what interviewers want to hear:
This question leads with the why-not, which is the more interesting answer. Interviewers ask it partly to test whether you reflexively reach for federation (a sign of over-engineering enthusiasm) or whether you reason about when it is appropriate.
The problem federation solves. An organization has many backend teams, all wanting to contribute fields to one GraphQL API. The naive solution has one team own the schema, with every other team sending it pull requests. That works at 5 teams. At 20 it breaks: the schema owners become a bottleneck, pull request queues grow, and no team ships independently. The alternative, each team running its own GraphQL API, solves the bottleneck but requires clients to fan out to many APIs, losing the single-endpoint ergonomics of GraphQL.
Federation solves this by splitting the schema responsibility: each team owns a subgraph that defines the types and fields in its domain, and a central router composes all the subgraphs into a single schema. Clients see one API. Teams deploy independently. The composition layer (schema checks, breaking change detection, type compatibility validation) runs at CI/CD time instead of in the router at runtime.
When you do not need it: the overhead is real. You need a router (an additional service to deploy, configure, and operate). You need a composition step in your CI/CD pipeline. Subgraph teams must learn the federation-specific directives (@key, @external, @requires, @provides) and the constraints they impose. Entity resolution via _entities adds a network round-trip compared to in-process resolution. For a team of five developers owning a GraphQL API that serves one frontend, all of that is cost the graph never earns back with no benefit. Federation is appropriate at the scale where the coordination overhead of managing a shared monolithic schema exceeds the operational overhead of the federation infrastructure.
The rule of thumb that plays well: if one team can fit in one room and owns the entire API and all the backing services, use a monolith. If teams deploy independently and the schema has grown to the point that PR-to-the-schema-team is a daily friction, evaluate federation.
One more thing separates a current answer from a dated one. Apollo's federation documentation is the reference for the implementation most interviews mean by the word. Apollo Federation is one implementation of the idea, and the GraphQL Foundation now has a vendor-neutral specification for the same problem, the GraphQL Federation spec, worked on by Apollo, ChilliCream, The Guild and WunderGraph together. Until September 2026 it was called Composite Schemas. It keeps the shape you already know, and renames the moving parts: an explicit @lookup field replaces the implicit _entities convention, and @require replaces @requires. If an interviewer asks where federation is going, that is the answer.
Question 2: What is an entity in federation, and what is a @key directive?
Short answer: An entity is a type in a federated graph that can be extended and resolved by multiple subgraphs. It is identified by a @key directive that names one or more fields that uniquely identify an instance of the type across the graph. The @key fields are the fields that subgraphs use to request entity data from each other through the router.
Why this is right / what interviewers want to hear:
The entity concept is the core mechanism of federation, and understanding it deeply requires understanding what problem it solves at the data-composition level.
In a non-federated graph, a Movie type is defined once in the schema and resolved by one service. In a federated graph, Movie might be defined and owned by the Movies subgraph (which knows the title, release year, and genre), but the Reviews subgraph also needs to attach Movie.averageRating to that type. The Reviews subgraph does not own the full Movie type, it only owns the rating data. But the schema should present Movie.averageRating as if it were a first-class field of Movie.
The @key directive is what makes this possible. The Movies subgraph declares Movie @key(fields: "id"), which means: "a Movie can be uniquely identified by its id field, and any other subgraph that wants to extend Movie can request a Movie by providing its id." The Reviews subgraph then declares extend type Movie @key(fields: "id") { averageRating: Float }, which means: "I am extending the Movie entity from another subgraph, identified by id, and adding the averageRating field."
The @key fields are how the router knows what to ask the originating subgraph when it needs to resolve an entity for another subgraph's extension. If a client asks for { movie(id: "42") { title averageRating } }, the router fetches title from the Movies subgraph and fetches averageRating from the Reviews subgraph. To do this, the router must know the id of the movie, which it gets from the @key, so it can pass it to the Reviews subgraph as an argument to the _entities query.
Composite keys are also possible: @key(fields: "namespace id") means the entity is uniquely identified by the combination of namespace and id. This is useful in multi-tenant systems where the same numeric ID may refer to different entities in different namespaces.
Question 3: What is the _entities query, and when does the router use it?
Short answer: _entities is a special GraphQL query that every federated subgraph exposes. It takes an array of "representations" (objects containing __typename and key field values) and returns the resolved entity objects. The router uses _entities when it needs to fetch fields for an entity that are owned by a subgraph that did not return the entity originally.
Why this is right / what interviewers want to hear:
The _entities query is the low-level mechanism that makes federation work at the network level. Understanding it means understanding how the router stitches together results from multiple subgraphs.
Consider a query: { movie(id: "42") { title averageRating } }. The router's plan:
- Send
{ movie(id: "42") { id title } }to the Movies subgraph. It returns{ "id": "42", "title": "Inception" }. - Construct an
_entitiesquery to send to the Reviews subgraph:{ _entities(representations: [{ "__typename": "Movie", "id": "42" }]) { ... on Movie { averageRating } } }. - The Reviews subgraph resolves
_entitiesby looking up movie 42 in its own database and returning{ averageRating: 4.7 }. - The router merges the two results and returns
{ id: "42", title: "Inception", averageRating: 4.7 }to the client.
This means every federated subgraph must implement the _entities query. In Apollo Federation-compatible server implementations (including Spring GraphQL with federation support), this is handled by the framework. The developer registers @ReferenceResolver methods that define how to load an entity from its key fields, and the framework exposes the _entities query automatically.
The performance implication: the _entities query is a batch query. When a client asks for { movies { title averageRating } } and the list returns 20 movies, the router sends one _entities request to the Reviews subgraph with 20 representations, and the Reviews subgraph returns 20 ratings. This is the federation equivalent of DataLoader batching: the router batches entity requests per subgraph instead of issuing one request per entity.
Question 4: How does the query planner decide whether to fetch subgraph data in parallel or sequentially?
Short answer: The query planner executes fetches in parallel when they do not depend on each other's results, typically when top-level fields come from different subgraphs. It executes sequentially when one subgraph's query needs data from another subgraph's response, specifically when an entity extension requires key fields that are returned by the first fetch.
Why this is right / what interviewers want to hear:
The query planner is the router component that takes a client query and produces a plan describing which subgraphs to query, in what order, with what arguments. Understanding the planner's parallelism model is important for reasoning about the latency cost of federated queries.
Parallel fetches: if a client query asks for { viewer { profile { name } } recommendation { title } }, and viewer comes from the Users subgraph and recommendation comes from the Recommendations subgraph, and neither depends on the other's result, the planner will fetch from both subgraphs simultaneously. The total latency is max(Users latency, Recommendations latency), not their sum.
Sequential fetches: if the Recommendations subgraph needs the viewer.id to return personalized recommendations, and viewer.id comes from the Users subgraph, then the planner must:
- Fetch
viewerfrom the Users subgraph to get theid. - Use that
idto fetch recommendations from the Recommendations subgraph.
These fetches are sequential. The total latency is Users latency + Recommendations latency. This is the federated query planning cost: cross-subgraph data dependencies create sequential fetches, which sum their latencies instead of taking the maximum.
The practical implication for schema design: fields that will often be queried together should be owned by the same subgraph if possible, or the owning subgraph should be queried first in the plan. The @requires directive is the mechanism for expressing data dependencies: @requires(fields: "viewerId") on a Recommendations field tells the planner that this field requires viewerId from another subgraph before it can be fetched.
Understanding query plan structure is also how you debug federation performance problems. Apollo GraphOS (and the rover subgraph check tool) can display the query plan for a given operation, showing exactly which subgraphs are called, in what order, and with what arguments.
Question 5: What does federated authorization mean, and where should auth decisions live in a federated graph?
Short answer: In a federated graph, the router handles authentication (verifying the JWT or session token) and forwards the principal to all subgraphs via a header. Each subgraph handles authorization (deciding what the principal can do) independently within its own resolvers. Authorization should not be centralized at the router, because the router does not know the domain logic that determines whether a given principal can access a given entity.
Why this is right / what interviewers want to hear:
Authentication vs. authorization is the fundamental distinction in this answer, and candidates who conflate the two will give an answer that is architecturally wrong.
Authentication at the router: the router receives the incoming request with a JWT or session cookie, validates it, and extracts the principal claims. It forwards them to subgraphs via a header, typically a serialized JSON object in an x-auth-user header, or the raw JWT for subgraphs that can validate JWTs independently. This is the right layer for authentication because authentication is a cross-cutting concern, every subgraph needs to know who is making the request, and the router is the choke point that sees all requests. Authenticating at the router avoids requiring each subgraph to implement JWT validation independently.
Authorization at the subgraph: each subgraph knows its own domain's access control rules. The Reviews subgraph knows that a reviewer can edit their own reviews but not others'. The Movies subgraph knows that a studio admin can update their studio's movies but not another studio's. These rules cannot be expressed generically at the router without the router becoming a domain-knowledge repository, which would violate the principle that subgraphs own their domain logic.
Authorization in the subgraph means: the subgraph reads the forwarded principal, applies domain-specific rules in the resolver or service layer, and returns either the data or an authorization error. @PreAuthorize in Spring, @RolesAllowed in Quarkus, or custom authorization logic in a service method are all appropriate.
The common mistake: teams that centralize all authorization at the router using a rules engine or a policy service. This works for coarse-grained authorization ("is the user logged in?", "does the user have the ADMIN role?") but fails for fine-grained authorization ("can this user edit this specific movie?"), because fine-grained rules require domain knowledge that belongs in the subgraph.
Question 6: What is a breaking change specific to federation (beyond standard GraphQL breaking changes)?
Short answer: Federation-specific breaking changes start with removing a @key directive, which leaves other subgraphs unable to resolve the entity they extend. Making a @key field nullable is another, because the router can no longer guarantee a complete representation. So is removing a @shareable or @provides annotation that other subgraphs depend on, or an @external field that another subgraph names in its @requires.
Why this is right / what interviewers want to hear:
Standard GraphQL breaking changes (removing fields, changing types) apply in federation too. Federation adds a new category: changes to composition metadata that break the router's ability to plan queries, even if the schema itself is technically valid.
Removing a @key: if the Movies subgraph removes @key(fields: "id") from Movie, the router can no longer use the _entities query to fetch Movie entities from any subgraph that extends Movie. The Reviews subgraph's averageRating field becomes unreachable, even though neither the Movies subgraph nor the Reviews subgraph has an invalid schema in isolation. The composition check in CI/CD should catch this, tools like rover subgraph check validate that the composed supergraph is still valid after a change.
Making a key field nullable: if Movie.id changes from ID! to ID, the router cannot reliably construct _entities representations, because a null id cannot identify an entity. This is a breaking change at the federation layer even if it is a non-breaking change at the GraphQL layer (making a non-null field nullable is safe for queries; it is not safe for entity resolution).
Removing @shareable: the @shareable directive marks a field as safe to resolve from multiple subgraphs. If the Movies subgraph declared Movie.title @shareable and the router is sending Movie.title resolution to either subgraph based on query plan optimization, removing @shareable means the router can only resolve title from one subgraph. This may change routing behavior and can break query plans that relied on the shared resolution.
@requires dependencies: if subgraph B declares averageRating @requires(fields: "viewCount") and subgraph A owns viewCount, then viewCount is an external field that subgraph B depends on. If subgraph A removes viewCount from its schema, composition fails because subgraph B has an unresolvable dependency.
These federation-specific breaking changes are why schema composition checks must run on every subgraph change, not just on the client-facing schema. A change to one subgraph that looks isolated can break the composed supergraph.
Further Reading
- Federation on graphql.org introduces the vocabulary without tying it to one vendor, which is the framing to bring into an interview.
- Apollo's federation documentation is the reference for the implementation most job descriptions mean, including
@key,@requiresand@provides. - The GraphQL Federation specification is the vendor-neutral work in progress, still at Stage 0, and naming it answers "where is this going?". It was called Composite Schemas until its rename on 2026-09-21.