8. Build check errors
10m

Overview

We've seen how and launches work in our development flow and what happens when the process goes smoothly without any errors. It's time to tackle what happens in the not-so-happy path, when changes to a subgraph result in composition errors.

In this lesson, we will:

  • Learn about the types of errors commonly encountered in supergraph composition
  • Learn how to navigate composition errors in Studio
  • Learn how to use the @inaccessible directive

Updating the subgraph

Let's return to our subgraph teams, who are hard at work improving Airlock. 👩🏽‍🚀 Achilles from the Accounts team has just made a few changes to the accounts subgraph's to bring visibility into a host's galactic coordinates.

In the , they've defined the GalacticCoordinates type the team has agreed on and included the two s: latitude and longitude.

subgraph-accounts/accounts.graphql
type GalacticCoordinates {
latitude: Float!
longitude: Float!
}

(Did you spot the mistake already? Don't worry, we'll get to that in a moment! Remember, this lesson is about what happens when things don't work the first time!)

They've also added a new to the Host entity: coordinates, which returns the GalacticCoordinates type.

subgraph-accounts/accounts.graphql
type Host implements User @key(fields: "id") {
#... other Host fields
"Where the host is primarily located"
coordinates: GalacticCoordinates
}

With these new additions in place, we're ready to help Achilles publish the changes and get this feature out into the world. Following the process we walked through in the previous lesson, the first thing on the list is using Rover to run a local check.

We'll open up a new terminal window and run the rover subgraph check command against Airlock's staging variant, including the file path and subgraph name parameters for the accounts .

rover subgraph check airlock-managed-fed@staging \
--schema "accounts.graphql" \
--name accounts

Right away, we see that something isn't quite right! Here's the error message we see in the terminal:

Checking the proposed schema for subgraph accounts against airlock-managed-fed@staging
error[E029]: Encountered 2 build errors while trying to build subgraph "accounts" into supergraph "airlock-managed-fed@staging".
Caused by:
Encountered 2 build errors while trying to build the supergraph.
INVALID_FIELD_SHARING: Non-shareable field "GalacticCoordinates.latitude" is resolved from multiple subgraphs: it is resolved from subgraphs "accounts" and "listings" and defined as non-shareable in subgraph "accounts"
INVALID_FIELD_SHARING: Non-shareable field "GalacticCoordinates.longitude" is resolved from multiple subgraphs: it is resolved from subgraphs "accounts" and "listings" and defined as non-shareable in subgraph "accounts"
The changes in the schema you proposed for subgraph accounts are incompatible with supergraph airlock-managed-fed@staging. See https://www.apollographql.com/docs/federation/errors/ for more information on resolving build errors.

The errors indicate that the GalacticCoordinates s (latitude and longitude) are resolved in both the accounts and listings subgraphs, but they're defined as non-shareable in the accounts subgraph. That's the subgraph Achilles was working on!

What they missed was adding the @shareable to the type definition, so let's make sure that's included.

subgraph-accounts/accounts.graphql
type GalacticCoordinates @shareable {
latitude: Float!
longitude: Float!
}

Achilles makes the update to their , and when we run the rover subgraph check command again, we can see that this fix has resolved the composition error!

Checking the proposed schema for subgraph accounts against airlock-managed-fed@staging
Check Result:
Compared 1 schema changes against 13 operations
┌────────┬─────────────┬───────────────────────────────────────────────┐
│ Change │ Code │ Description │
├────────┼─────────────┼───────────────────────────────────────────────┤
│ PASS │ FIELD_ADDED │ type `Host`: field `coordinates` added │
└────────┴─────────────┴───────────────────────────────────────────────┘
View full details at https://studio.apollographql.com/graph/airlock-managed-fed/operationsCheck/{URL}

Achilles continues to work on their subgraph, adding the necessary s and methods to implement their additions.

Adding new shared fields

Before pushing their changes up to the codebase, Achilles meets with the Airlock team and finds out that the project mockup designs have been updated! In addition to the numerical coordinates, users also want to know the local name of the location. For example, it's easier for guests to immediately understand "Planet Z" compared to "83.0405 latitude and 35.2034 longitude" (but they'll still also need to know the precise coordinates).

Achilles adds a new to the GalacticCoordinates type: nickname, which returns a String.

subgraph-accounts/accounts.graphql
type GalacticCoordinates @shareable {
latitude: Float!
longitude: Float!
nickname: String
}

Awesome! This new is already being returned by the AccountsAPI service, so there are no additional changes to be made in the s or files. Achilles is so excited to get this feature out, they forget to rerun the rover subgraph check command locally again. Instead, they push the change straight up to the GitHub codebase and create a PR. This triggers the Schema Checks job.

Oh no, the job failed!

https://github.com
Screenshot of the GitHub PR with the job failed and link to the Studio Checks page

Not to worry, that means our pipeline caught an error before it made it to production! We can investigate exactly why the job failed by following the link to Apollo Studio's Checks page embedded in the PR.

Schema checks in Apollo Studio

The Checks page in Studio shows us the results of the check so we can diagnose what went wrong.

https://studio.apollographql.com
Screenshot of the failed check in Studio Checks page

Studio identifies the subgraph that failed to compose and indicates what went wrong in the process. And because failing composition means no new is generated, the continues to process requests based on its existing valid version of the . So even though the Accounts team's changes aren't working, clients using the staging variant of the graph don't encounter any errors! This gives the Accounts team a chance to review the error and push a fix before merging their PR.

This is the error we see:

error[E029]: Encountered 1 build error while trying to build subgraph "accounts" into supergraph "airlock-managed-fed@staging".
Caused by:
Encountered 1 build error while trying to build the supergraph.
SATISFIABILITY_ERROR: The following supergraph API query:
mutation {
updateListing(listingId: "<any id>", listing: {}) {
listing {
coordinates {
nickname
}
}
}
}
cannot be satisfied by the subgraphs because:
- from subgraph "listings":
- cannot find field "GalacticCoordinates.nickname".
- cannot move to subgraph "accounts", which has field "GalacticCoordinates.nickname", because type "GalacticCoordinates" has no @key defined in subgraph "accounts".

Let's investigate the error further.

When trying to build the , we ran into a SATISFIABILITY_ERROR. This error means that our subgraphs might appear compatible on the surface, but the resulting API would include at least one that the subgraphs can't satisfy.

The error message provides an example , along with two reasons why our subgraphs can't satisfy it:

First, the listings subgraph can't find the GalacticCoordinates.nickname. Achilles had only added the nickname to the accounts subgraph (the subgraph their team is responsible for). The listings subgraph has no such .

Second, the listings subgraph can't pass the responsibility of resolving the nickname to the accounts subgraph, because GalacticCoordinates isn't an entity, it's a value type. Remember that only entities (types with the @key ) can resolve different s across multiple subgraphs.

The s of a value type can differ across subgraphs in some ways, but we can't omit shared s. We need to add this new GalacticCoordinates.nickname to both the accounts and listings subgraphs.

Note: You can learn more about the different ways shared s can differ in value types in the Apollo docs on sharing types.

To incrementally add the to all of our subgraphs without breaking composition, we can use the @inaccessible .

The @inaccessible directive

The @inaccessible is applied to a in a subgraph . Whenever it's present on a , composition omits that from the 's API . This means that clients can't include the in s. This helps us incrementally add a to multiple subgraphs without breaking composition.

Note that we only need to apply the @inaccessible to one of the subgraphs where the is defined.

Let's use the @inaccessible to incrementally add the nickname to the GalacticCoordinates value type. Here's the plan:

👩🏽‍🚀 In the accounts subgraph:

  • Achilles will add the GalacticCoordinates.nickname field and apply the @inaccessible directive.
  • We'll use our automated CI/CD process to ensure these schema additions make their way to the staging variant in the registry.

👩🏽‍🏫 Then, in the listings subgraph:

  • Lisa will add the GalacticCoordinates.nickname field. We don't need to apply @inaccessible because it's already taken care of in the accounts subgraph.
  • We'll use our automated CI/CD process to ensure these schema additions make their way to the staging variant in the registry.

👩🏽‍🚀 With the new shared field added to all the subgraphs that use the value type, we can finally go back to the accounts subgraph:

  • Achilles will remove the @inaccessible directive from the GalacticCoordinates.nickname field. This allows the field to be included in the composition and compose successfully, because the listings subgraph now includes the nickname field.
  • We'll use our automated CI/CD process to ensure these schema additions make their way to the staging variant in the registry.

Let's get to it!

Using the @inaccessible directive

👩🏽‍🚀 In the accounts subgraph, Achilles will add the @inaccessible after the return type of the nickname .

subgraph-accounts/accounts.graphql
type GalacticCoordinates @shareable {
latitude: Float!
longitude: Float!
nickname: String @inaccessible
}

Achilles also needs to make sure the is included in the import array at the top of the .

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

And that's it! With these changes in place, let's try running a local check.

rover subgraph check airlock-managed-fed@staging \
--schema "./accounts.graphql" \
--name accounts

In the terminal, we'll see:

Checking the proposed schema for subgraph accounts against airlock-managed-fed@staging
Compared 1 schema changes against 16 operations
┌────────┬─────────────┬────────────────────────────────────────┐
│ Change │ Code │ Description │
├────────┼─────────────┼────────────────────────────────────────┤
│ PASS │ FIELD_ADDED │ type `Host`: field `coordinates` added │
└────────┴─────────────┴────────────────────────────────────────┘

Awesome, the checks pass with no errors! The addition of the nickname doesn't show up in the check because it's currently marked as @inaccessible. We'll push the changes up to GitHub and let the CI run its as well. When those pass, we can merge the PR, automatically triggering the deploy process to deploy the changes to the accounts subgraph staging environment in Heroku and the Airlock graph staging variant in the Apollo .

Adding the new shared field to the listings subgraph

👩🏽‍🏫 Back over to the listings subgraph, Lisa will add the nickname to the GalacticCoordinates value type.

subgraph-listings/listings.graphql
type GalacticCoordinates @shareable {
latitude: Float!
longitude: Float!
nickname: String
}

This new is already being returned by the ListingsAPI service, so there are no additional changes to be made in the s or files. We can follow the CI/CD process and get these changes up on the listings subgraph staging environment in Heroku and the Airlock graph staging variant in the Apollo !

Removing the @inaccessible directive

👩🏽‍🚀 With the GalacticCoordinates.nickname defined in every subgraph that uses the value type, Achilles is ready to remove the @inaccessible from the GalacticCoordinates.nickname .

subgraph-accounts/accounts.graphql
type GalacticCoordinates @shareable {
latitude: Float!
longitude: Float!
nickname: String
}

That's it! We can follow the same CI/CD process we're used to by now and get these changes up on staging!

This time the check will show that the nickname was successfully added:

Checking the proposed schema for subgraph accounts against airlock-managed-fed@staging
Compared 1 schema changes against 16 operations
┌────────┬─────────────┬────────────────────────────────────────────────────┐
│ Change │ Code │ Description │
├────────┼─────────────┼────────────────────────────────────────────────────┤
│ PASS │ FIELD_ADDED │ type `GalacticCoordinates`: field `nickname` added │
└────────┴─────────────┴────────────────────────────────────────────────────┘

After we've validated that everything in the staging environment looks good, we're ready to deploy to production! We've already gone over those steps in the previous lesson, so feel free to refer to that section if you need a refresher.

We've improved on our Project Galactic Coordinates by adding a familiar nickname to the coordinates. This feature is officially out in the world and ready to be used by clients!

Practice

Which of the following statements about build checks are true?

Key takeaways

  • We use the rover subgraph check command to perform schema checks locally.
  • The output of schema checks can be viewed in Studio, as well as locally with the Rover CLI.
  • To add a new shared field to a value type, we should first apply the @inaccessible directive to the field. Then, we can incrementally add the new field to each subgraph that defines the value type. Finally, we can remove the @inaccessible directive and the field will be officially part of the supergraph schema.

Up next

In the next lesson, we'll learn about checks, and how Studio validates proposed changes against the way clients have historically consumed data from the graph.

Previous
Next