Docs
Try Apollo Studio

Moving to Apollo Federation 2

Upgrade your supergraph incrementally at any pace


📣 If you haven't yet, see what's new in Federation 2.

You can (and should!) move your Apollo Federation 1 supergraph to Federation 2 incrementally, one component at a time. Your supergraph will work as expected after each step in the process, even if some of your subgraphs continue using Federation 1 schemas.

Each individual step of moving your supergraph has its own benefits, so it's useful to complete as many steps as you're ready to complete. You can always finish the rest later.

Here are the three steps for moving to Federation 2:

Update your gateway
Use Federation 2 composition
Update individual subgraphs
  1. Update your gateway to a version that supports Federation 2.
    • Alternatively, you can swap out your Node.js gateway for the Apollo Router.
  2. Begin composing your supergraph schema with Federation 2 composition logic.
  3. Update your individual subgraphs to use Federation 2 features and directives.

Steps 1 and 2 are quick, and it's straightforward to reverse them if you need to for any reason. Step 3 requires schema changes that remove backward compatibility with Federation 1. Because of this, we recommend first completing it with a test instance of your graph.

If you encounter an issue while moving your supergraph to Federation 2, please describe the issue in the community forums.

Step 1: Update your gateway

The @apollo/gateway library supports Federation 2 supergraph schemas in version 2.0.0 and later. These versions of @apollo/gateway require version 16.0.0 or later of the graphql library.

You can install updated versions of these libraries in your gateway project with the following command:

npm install @apollo/gateway graphql

Alternatively, you can swap out your Node.js gateway for the Apollo Router, a high-performance graph router implemented in Rust. See the docs.

Both @apollo/gateway v2.x and the Apollo Router support Federation 1! You can update to either without making any other changes, and your Federation 1 supergraph will work as expected.

Step 2: Configure your composition method

Federation 2 uses a completely new method to compose supergraph schemas. This method is backward compatible with Federation 1 subgraph schemas, and it provides the following benefits even for Federation 1 subgraphs:

  • Helpful composition hints when schema definitions are inconsistent between your subgraphs
  • Support for interfaces implementing other interfaces (which Federation 1 composition doesn't support)

Follow the instructions below to configure whichever composition method(s) you currently use:

After you configure these changes, make sure your gateway is using your newly created Federation 2 supergraph schema. (If you're using managed federation, your gateway will fetch the new schema from Apollo automatically.)

Your Federation 1 subgraphs are now composed using Federation 2 composition! The natural next question is, "What does this change about the behavior of those subgraphs?" And until the next step, the answer is: nothing!

If your supergraph is not successfully composing with Federation 2, see Breaking changes for the most common causes.

Step 3: Update individual subgraphs

You can update your subgraphs one at a time! The steps below describe how to modify a single subgraph for Federation 2, and you can perform these steps for a given subgraph whenever's convenient for your team.

Federation 2 provides powerful new features that require making some changes to your subgraphs. These features include:

  • Selectively sharing types and fields across subgraphs with @shareable
  • Safely migrating fields from one subgraph to another with @override
  • Hiding internal routing fields from graph consumers with @inaccessible

The schema changes you make are backward incompatible with Federation 1, which means you won't be able to use Federation 1 composition anymore unless you revert those changes.

Update your subgraph library

To use new Federation 2 features and their associated directives, it's helpful to update your subgraph library to a version that automatically supports those directives.

  • If your subgraph uses Apollo Server and the @apollo/subgraph library, update @apollo/subgraph to version 2.0.0 or later like so:

    npm install @apollo/subgraph
  • If your subgraph uses another server library, check the compatibility table to see whether it supports Federation 2 directives yet. If it does, consult that library's documentation to determine which version you need to update to.

    • If your library doesn't support Federation 2 directives yet, you can still use that library with Federation 2 if the library lets you add custom directive definitions to your schema!

Opt in to Federation 2

Add the following definition to your subgraph schema:

extend schema
@link(url: "https://specs.apollo.dev/federation/v2.0",
import: ["@key", "@shareable"])

This definition identifies a schema as a Federation 2 schema, and it imports any federation-specific directives that the schema uses. Without this @link definition, composition considers a schema to be a Federation 1 schema, and it applies certain default settings for backward compatibility.

⚠️ Important: Depending on your schema, you might need to add other federated directives to the import array, such as @external or @provides.

See all Federation-specific directives.

Add directive definitions if needed

Currently, not all subgraph libraries provide built-in support for Federation 2 directives (such as @shareable). If your library doesn't provide this support, you need to add the following directive definitions to your subgraph schema:

Some subgraph libraries are "code-first" (they dynamically generate their schema from code) instead of "schema-first" (they use a static schema file). For code-first libraries, manually adding these directive definitions is less straightforward. If you encounter this with your library, please let us know by submitting an issue.

We'll be working with library maintainers to help automatically add these schema definitions in more subgraph libraries.

Mark all value types as @shareable

By default in Federation 2, most schema fields are resolvable by only a single subgraph. In Federation 1, this is not true for value types:

Fed. 1 (invalid in Fed. 2)

Subgraph A
type Position {
x: Int!
y: Int!
}
Subgraph B
type Position {
x: Int!
y: Int!
}

For both subgraphs to resolve the above fields in Federation 2, the @shareable directive is required in both schemas:

Fed. 2

Subgraph A
type Position {
x: Int! @shareable
y: Int! @shareable
}
Subgraph B
type Position {
x: Int! @shareable
y: Int! @shareable
}

You can also apply @shareable directly to a type definition (such as Position above). This is equivalent to applying @shareable to all of that type's fields.

For more details, see Value types.

Update entity definitions

Federation 2 introduces subtle but powerful changes to entities. These changes require corresponding updates to their definitions in your subgraph schemas.

Remove unnecessary syntax

In Federation 1, an entity originates in one subgraph, and then other subgraphs extend the entity to add fields:

Fed. 1

Products (originating)
type Product @key(fields: "id") {
id: ID!
name: String!
price: Int
}
Inventory (extending)
extend type Product @key(fields: "id") {
id: ID! @external
inStock: Boolean!
}

In Federation 2, entities no longer have an originating subgraph. Instead, each subgraph can define an entity and contribute fields to it:

Fed. 2

Products
type Product @key(fields: "id") {
id: ID!
name: String!
price: Int
}
Inventory
type Product @key(fields: "id") {
id: ID!
inStock: Boolean!
}

Note the following in the Federation 2 subgraphs above:

  • The Inventory subgraph no longer extends the Product entity.
  • The Inventory subgraph no longer marks the Product.id field as @external.
    • The @external directive is no longer required for @key fields, but it is still required for @requires and @provides.
  • Both subgraphs can resolve Product.id, even though it isn't marked as @shareable!
    • Unlike most fields, @key fields such as Product.id are @shareable by default. This is necessary for @key fields, because the gateway uses them to associate data from different subgraphs with the same object.

Mark @provides fields as @shareable

The @provides directive enables a subgraph to resolve a particular field only for specific query paths. It's supported in Federation 2 as it is in Federation 1.

However, if a subgraph @provides a particular field, that field must be marked as @shareable in each subgraph where it's always resolvable:

Fed. 2

Products
type Product @key(fields: "id") {
id: ID!
name: String! @shareable
price: Int
}
Inventory
type Product @key(fields: "id") {
id: ID!
name: String! @external
inStock: Boolean!
}
type Query {
outOfStockProducts: [Product!]! @provides(fields: "name")
}

Here, Query.outOfStockProducts in the Inventory subgraph @provides the Product.name field. Therefore, that field must be marked as @shareable in the Products subgraph (and @external in the Inventory subgraph, as in Federation 1). Otherwise, a composition error occurs.

Modify @keys for entity stubs

In certain cases, a subgraph references an entity without contributing any fields to it. In Federation 1, these cases look like the following:

Fed. 1

Products
type Product @key(fields: "id") {
id: ID!
name: String!
price: Int
}
Reviews
type Product @key(fields: "id") {
id: ID!
}
type Review {
product: Product!
score: Int!
}

The Reviews subgraph above uses Product as the return type of the Review.product field, so it needs to define a "stub" of the Product entity. This stub includes just enough information to identify a unique instance.

In Federation 2, stubs like Product should include resolvable: false in their @key arguments, like so:

Fed. 2

Products
type Product @key(fields: "id") {
id: ID!
name: String!
price: Int
}
Reviews
type Product @key(fields: "id", resolvable: false) {
id: ID!
}
type Review {
product: Product!
score: Int!
}

Setting resolvable: false tells the gateway that a subgraph doesn't define a reference resolver for a particular entity. This is most common when referencing an entity without contributing fields to it.


You're done! You should now have a Federation 2 supergraph that composes successfully and takes full advantage of new federation features. If you encounter an issue, please let us know in the community forums.

Edit on GitHub
Previous
☀️ New in Federation 2
Next
⬅️ Backward compatibility