Docs
Launch GraphOS Studio
You're viewing documentation for a previous version of this software. Switch to the latest stable version.

Introduction to Apollo Federation

Implement a single graph across multiple services


📣 Apollo Federation 2 is generally available! View the Federation 2 docs.

To get the most out of GraphQL, your organization should expose a single graph that provides a unified interface for querying any combination of your backing s. However, it can be challenging to represent an enterprise-scale graph with a single, monolithic GraphQL server.

To remedy this, you can use Apollo Federation to divide your graph's implementation across multiple back-end services (called subgraphs):

Graph router
Users
subgraph
Products
subgraph
Reviews
subgraph
Web app
iOS app

Unlike other distributed GraphQL architectures (such as stitching), Apollo Federation uses a declarative programming model that enables each to implement only the part of your composed supergraph that it's responsible for.

Apollo Federation also supports a free managed mode with Apollo Studio, which enables you to add, remove, and refactor your s without requiring any downtime for your production graph.

Architecture

An Apollo Federation architecture consists of:

  • A collection of subgraphs (usually represented by different back-end services) that each define a distinct GraphQL
  • A gateway that uses a supergraph schema (composed from all s) to execute queries across multiple subgraphs

Apollo Server provides libraries for acting both as a and as a gateway, but these components can be implemented in any language and framework.

Apollo Federation does not currently support GraphQL subscription operations.

The following presentation by Mandi Wise further describes the architecture of Apollo Federation and walks through implementing a federated graph:

Design principles

Incremental adoption

Like the rest of the Apollo platform, Apollo Federation can (and should) be adopted incrementally:

In both of these cases, all of your clients will continue to work throughout your incremental migration. In fact, clients have no way to distinguish between different graph implementations.

Separation of concerns

Apollo Federation encourages a design principle called separation of concerns. This enables different teams to work on different products and features within a single graph, without interfering with each other.

Limitations of type-based separation

When considering how to split a single GraphQL across multiple s, it seems straightforward to divide schemas up by type. For example, a users would define the entirety of a User type, the products would define a Product type, and so on:

3 separate types divided into 3 services

Although this separation looks clean, it quickly causes issues. Specifically, a particular feature (or concern) usually spans multiple types.

Consider the recentPurchases of the User type in the above . Even though this is a member of the User type, a list of Products should probably be populated by the products , not the users .

By defining the recentPurchases in the products instead:

  • The that defines the is also the subgraph that knows how to populate the field. The users might not even have access to the back-end data store that contains product data.
  • The team that manages product data can contain all product-related logic in a single that they own unilaterally.

Concern-based separation

The following uses Apollo Federation to divide the same set of types and s across the same three s:

Splitting those 3 types by data source rather than by type. Includes type extensions across services

The difference is that now, each defines the types and s that it is capable of (and should be responsible for) populating from its back-end data store.

The result is the best of both worlds: an implementation that keeps all the code for a given feature in a single and separated from unrelated concerns, and a product-centric with rich types that reflects the natural way an application developer would want to consume the graph.

Federated schemas

A federated graph uses multiple "types" of GraphQL s:

  • Subgraph schemas. Each of your subgraphs has a distinct that indicates which types and s of your composed supergraph it's responsible for resolving.
  • Supergraph schema. This is the result of performing composition on your collection of s. It combines all of the types and s from your subgraph schemas, plus some federation-specific s that tell your gateway which s are responsible for resolving which s.
  • API schema. This is like the schema, but it omits types, s, and s that are considered "machinery" and are not part of your public API (this includes federation-specific directives).
    • This is the that your gateway exposes to your GraphQL API's consumers, who don't need to know any internal implementation details about your graph.
(Remove routing machinery)
API schema
(A + B + C)
Supergraph schema
(A + B + C + routing machinery)
Subgraph schema
A
Subgraph schema
B
Subgraph schema
C

Let's look at an example!

Subgraph schemas

Below, we define the s for three s in a basic e-commerce application. Each subgraph is implemented as a standalone back-end service:

accounts
extend type Query {
me: User
}
type User @key(fields: "id") {
id: ID!
username: String!
}
products
extend type Query {
topProducts(first: Int = 5): [Product]
}
type Product @key(fields: "upc") {
upc: String!
name: String!
price: Int
}
reviews
type Review {
body: String
author: User @provides(fields: "username")
product: Product
}
extend type User @key(fields: "id") {
id: ID! @external
username: String! @external
reviews: [Review]
}
extend type Product @key(fields: "upc") {
upc: String! @external
reviews: [Review]
}

These s illustrate several important conventions of Apollo Federation:

  • A can reference a type that's defined by another . For example, the Review type includes a product of type Product, even though the Product type is defined in a different .

  • A can also extend a type that's defined by another . For example, the reviews extends the User type by adding a reviews to it.

  • A must add the @key to an 's definition in order for other s to be able to reference or extend that type. This makes an an entity.

Supergraph schema

To create our , we perform composition on our collection of subgraph schemas. With managed federation, Apollo performs composition automatically whenever one of your s registers an updated .

We can also perform composition manually with the CLI:

rover supergraph compose --config ./supergraph.yaml

For an example configuration file, see the Rover docs.

This outputs the following that our gateway can use to route queries to the correct s:

As you can see, the includes a lot of federation-specific additions! These additions are used only by the gateway, and you'll never need to add them manually.

API schema

The gateway uses its supergraph schema to produce an API schema, which is what's exposed to clients as your actual GraphQL API. This cleanly and logically represents the combination of your subgraph schemas:

Gateway example

You provide a composed supergraph schema to the ApolloGateway constructor, like so:

const supergraphSdl = readFileSync('./supergraph.graphql').toString();
const gateway = new ApolloGateway({
supergraphSdl
});
const server = new ApolloServer({ gateway });
server.listen();

That’s it! With Apollo Federation, s live in your s. The gateway serves only to plan and execute GraphQL s across those subgraphs.

Now we can execute GraphQL s against our gateway just as if it were implemented as a single, monolithic GraphQL server:

# A query that the gateway resolves by calling all three services
query GetCurrentUserReviews {
me {
username
reviews {
body
product {
name
upc
}
}
}
}

Managed federation

In addition to providing its on startup, Apollo Gateway can operate in managed federation mode, where Apollo Studio acts as the source of truth for each 's .

This mode enables multiple teams working on a graph to coordinate when and how underlying s change. It's recommended for all federated graphs. For more information, read Managed federation overview.

Apollo Server libraries

Apollo Server supports Apollo Federation via two open-source extension libraries:

  • @apollo/subgraph provides primitives that s use to make their individual GraphQL s composable.
  • @apollo/gateway enables you to set up an instance of Apollo Server as a gateway that distributes incoming GraphQL s across one or more s.

Ready to try out Apollo Federation? Jump into the Quickstart!

Next
Part 1 - Local schema composition
Edit on GitHubEditForumsDiscord