Docs
Launch GraphOS Studio

Schema checks

Validate all proposed changes to your schema are safe


Certain changes to your 's schema (such as removing a or type) might break one of your application's clients. help you identify breaking changes before you make them. They can also help you identify when a potentially dangerous change is in fact safe.

You can review the results of inside from your graph's Checks page, helping you make informed decisions about evolving your graph:

Schema check results in Studio

With the exception of

, are free as part of
all Apollo plans
.

Types of checks

can perform the following types of :

  • : For , verify whether your proposed changes to a will successfully compose with your other subgraph schemas.

  • : Compare your proposed schema changes against historical to verify whether the changes will break any of your 's active clients.

  • : Analyze your proposed schema changes for violations of formatting rules and other best practices.

  • (Enterprise only): Check whether your proposed schema changes have matching and approved
    schema proposals
    .

  • (Enterprise only): When running on a , also check whether your proposed schema changes will break any downstream variants.

Most of this article covers and checks.

Prerequisites

To enable for your , do the following if you haven't yet:

  1. Make sure you've published all your to , and that those schemas are up to date.

  2. For checks, make sure your is sending operation metrics to . GraphOS uses historical metrics to determine whether a potentially dangerous schema change is safe.

    ⚠️ CAUTION

    If has no metrics to compare against, all potentially dangerous schema changes result in a failed check.

  3. in your development environment and
    authenticate it with GraphOS
    .

Running your first check

Let's say you've made local changes to one of your . After you

, you can run against those changes with the rover subgraph check command.

NOTE

If you have a

(which is not recommended), use
rover graph
commands instead of rover subgraph commands.

The rover subgraph check command looks like this:

rover subgraph check docs-example-graph@main --name products --schema ./schema.graphql

It requires the following:

  • Your registered 's graph ref, which a string with the format graph-id@variant-name (for example, docs-example-graph@main). This is available from your 's README page in .

  • The locally modified version of your schema. In the command above, the schema is provided via a .graphql file.

    • If your schema is not in a standalone .graphql file, you can run your locally and pipe its schema directly from rover graph introspect, like so:

      rover subgraph introspect http://localhost:4000 | rover subgraph check docs-example-graph@main --name products --schema -

Try changing something in the local version of your schema and see what happens! If everything is set up correctly, the command's output looks similar to the output shown in

.

The checks lifecycle

When you run rover subgraph check:

  1. generates a diff between your local schema and the published schema for the you're checking against.
  2. uses this diff to determine whether the changes affect any that have been executed against your within a
    customizable time window
    (by default, this is the last seven days).
  3. returns the diff, along with a list of the that are affected by the changes.
  4. prints the result of the check and returns a non-zero exit code if at least one breaking change is found.

The check response

Running rover subgraph check outputs the diff of all detected schema changes and highlights breaking changes:

$ rover subgraph check docs-example-graph@current --subgraph products --schema ./schema.graphql
Validated the proposed subgraph against metrics from docs-example-graph@current
Compared 1 schema changes against 24 operations
┌────────┬────────────────────┬─────────────────────────────────────────────────────────┐
│ Change │ Code │ Description │
├────────┼────────────────────┼─────────────────────────────────────────────────────────┤
│ PASS │ FIELD_CHANGED_TYPE │ field `Query.books`: type `[Book]` changed to `[Book!]` │
└────────┴────────────────────┴─────────────────────────────────────────────────────────┘
View full details at https://studio.apollographql.com/service/docs-example-graph/checks/<DETAILS>

Each change to the schema is labeled either PASS or FAIL.

NOTE

Because breaking changes are detected by analyzing recent , your must

for to work. If there are no metrics to compare against, all potentially dangerous schema changes are labeled FAIL.

The rover subgraph check command returns a nonzero result if any check fails.

The output also includes a Studio URL that provides full details on the changes and their impact on existing clients and :

Service check page in GraphOS Studio

If you've

, the "Details" link in your GitHub check takes you to this same details page.

If you run a check within a Git repository, rover subgraph check sends both the commit hash and that hash's author to to display on the check. If you haven't

, the author appears as "Unknown." If you want to override author, commit, or other values, you can
set environment variables in Rover
to do so.

Rerunning checks

You can rerun checks from . Select the check and click Rerun check.

Rerun check in GraphOS Studio

When you do, the new run uses the current

, regardless of the configuration at the time of the original run. Similarly, the new run's time window is based on the current time, not the time when the original check ran.

The new checks run incorporates any changes made to excluded or included clients, checked , and any marked as safe or ignored.

NOTE

If you've

, a rerun of the check also updates the status of the check in GitHub.

Composition checks

When you run rover subgraph check, performs a composition check before it performs any other checks. A check verifies that changes you make to a are valid definitions and are compatible with your other subgraph schemas, enabling them to compose into a for your (

).

If a check fails, Studio does not then perform additional checks for the provided schema.

From your 's Checks page in , you can click a particular check to view its result. If composition succeeded, you can view the composed . Regardless of success, you can view the proposed .

Operation checks

If a

succeeds, then validates schema changes with operation checks. These checks use your 's historical client data to determine whether any clients would be negatively affected by the proposed schema changes. For example, the changes might include removing a that multiple clients currently include in their queries.

Overriding flagged changes

Occasionally, might flag a change that you know is safe. For example, you might change an input type's from nullable to non-nullable (usually a breaking change) when you're certain that your clients never provide a null value for the field.

In cases like this, you can override a flagged change in from the associated check's details page:

Service check page in GraphOS Studio

NOTE

Only

can override checks.

You override flagged changes on an -by-operation basis. For each operation with flagged changes, you can override those changes in the following ways:

  • Mark the changes as safe. In this case, will not flag these exact changes for the in any future execution. This effectively "approves" the changes for the operation.
    • If a future check detects approved changes along with new unsafe changes to the , the new unsafe changes will be flagged.
  • Ignore the operation. In this case, will completely ignore the when checking all changes in any future execution.
    • This option is useful when you know an originates only from clients or client versions that you don't actively support.

Linter checks

For more info on linter checks, see

.

Proposals checks

This feature is only available with a

.
You can test it out by signing up for a free
Enterprise trial
.

For more info on proposals checks, see the

.

Contract checks

This feature is only available with a

.
You can test it out by signing up for a free
Enterprise trial
.

For more info on checks, see the

.

Using in CI

are especially useful when you add them to your CI pipeline (such as Jenkins or CircleCI). By doing so, you can obtain check results and display them directly on your team's pull requests.

We recommend defining a separate CI job for each

(production, staging, etc.) that you want to validate your changes against. The rover subgraph check command returns a non-zero exit code when it detects a breaking change, meaning the job fails when the check fails.

Authenticating Rover

The rover config auth command is interactive, which means you shouldn't use it in CI environments. Instead, you can authenticate with Studio by setting the APOLLO_KEY environment variable in CI. For details, see

.

Example configuration

The following config defines a schema check job for a CircleCI pipeline. Your config's syntax varies depending on your CI tool, but the job's steps are the same.

config.yml
version: 2
jobs:
# ...other jobs...
# Define a separate job for each environment you validate against.
check_against_staging:
docker:
- image: circleci/node:12
steps:
- checkout
- run: npm install
# Start the GraphQL server. If a different command is used to
# start the server, use it in place of `npm start` here.
- run:
name: Starting server
command: npm start
background: true
# Make sure the server has enough time to start up before running
# commands against it.
- run: sleep 5
# In CI environments, this command authenticates via the `APOLLO_KEY`
# environment variable.
- run: rover subgraph check docs-example-graph@current --name products --schema ./schema.graphql

Integrating with GitHub

If you're using GitHub, you can install the

. This app enables to send a webhook back to your GitHub project on each call to rover subgraph check, providing built-in pass/fail status checks on your pull requests:

GitHub Status View

Integrating with other version control services

If you're using GitHub Enterprise, Bitbucket, or another version control service, we recommend setting up your CI tool to post a comment on each pull request with the results of . By surfacing schema diffs and breaking changes directly in your PR, you can avoid searching your CI logs to determine why a check failed.

Customizing checks

See

.

Types of schema changes

Not every change to a schema is a potentially breaking change. Additive changes (such as adding a to a type) are usually safe and do not affect active clients. Deletions and modifications (such as removing a field or changing a return type), however, can break clients that use affected types and fields.

Potentially breaking changes

Removals

These changes remove a schema element. If a removed element is actively being used by an , that operation will start returning an error.

NameDescription
FIELD_REMOVEDA field used by at least one operation was removed.
TYPE_REMOVEDA scalar or object used by at least one operation was removed.
ARG_REMOVEDAn argument used by at least one operation was removed from a field.
TYPE_REMOVED_FROM_UNIONA type was removed from a union used by at least one operation.
INPUT_FIELD_REMOVEDA field was removed from an input type. That field is referenced by an argument on another field that's used by at least one operation.
VALUE_REMOVED_FROM_ENUMA value was removed from an enum used by at least one operation.
TYPE_REMOVED_FROM_INTERFACEAn object was removed from an interface used by at least one operation.

Addition of required arguments

These changes add a required input to a schema element. If an is actively using an element of your and doesn't add the new required input , the graph will return an error to affected clients.

NameDescription
REQUIRED_ARG_ADDEDA non-nullable argument was added to field that's used by at least one operation.
NON_NULL_INPUT_FIELD_ADDEDA non-nullable field was added to an input object used by at least one operation.

In-place updates

These changes update an existing schema element. If an is actively using an element that is updated, the operation might start receiving an error from your . It also might receive an unexpected result.

NOTE

In some cases, in-place updates are compatible with affected clients at runtime (such as a type rename or a conversion from an object to an interface that uses the same ). However, still marks these as breaking changes, because validation does not have enough information to ensure that they are safe.

NameDescription
FIELD_CHANGED_TYPEAn existing field used by at least one operation changed its type.
INPUT_FIELD_CHANGED_TYPEAn existing field of an input object changed its type. That field is referenced by an argument on another field that's used by at least one operation.
TYPE_CHANGED_KINDAn existing type used by at least one operation changed its "kind." For example, an object type was changed to a union type.
ARG_CHANGED_TYPEAn existing argument on a field used by at least one operation changed its type.

Default arguments

These changes update the default value for an . If an is using an element of your and does not specify a value for this argument, the operation might get an unexpected result when the schema is updated if it was relying on the original default value.

NameDescription
ARG_DEFAULT_VALUE_CHANGEAn existing field used by at least one operation had a default value added or changed.

Non-breaking changes

These changes are detected by , but they are "safe." They never affect the behavior of any existing clients if deployed.

Schema additions

NameDescription
FIELD_ADDEDA field was added to an existing type.
TYPE_ADDEDA type was added to the schema.
VALUE_ADDED_TO_ENUMA value was added to an enum. If clients contain a switch statement on the enum's value and do not include a default case, this change might cause unexpected behavior.
TYPE_ADDED_TO_UNIONA type was added to a union used by at least one operation.
TYPE_ADDED_TO_INTERFACEAn interface was applied to an object used by at least one operation.
OPTIONAL_ARG_ADDEDA nullable argument was added to an existing field.
NULLABLE_FIELD_ADDED_TO_INPUT_OBJECTA nullable field was added to an existing input object.

Deprecations

NameDescription
FIELD_DEPRECATEDAn existing field was deprecated.
FIELD_DEPRECATION_REMOVEDA previously deprecated field is no longer deprecated.
FIELD_DEPRECATED_REASON_CHANGEThe specified reason for a field's deprecation changed.
ENUM_DEPRECATEDAn existing enum was deprecated.
ENUM_DEPRECATION_REMOVEDA previously deprecated enum is no longer deprecated.
ENUM_DEPRECATED_REASON_CHANGEThe specified reason for an enum's deprecation changed.

Descriptions

NameDescription
TYPE_DESCRIPTION_CHANGEAn existing type's description changed.
FIELD_DESCRIPTION_CHANGEAn existing field's description changed.
ENUM_VALUE_DESCRIPTION_CHANGEAn existing enum value's description changed.
ARG_DESCRIPTION_CHANGEAn existing argument's description changed.

Limits

Operation check cardinality

checks will run against a maximum of 10,000 distinct operations. A warning message will display on the UI when a larger cardinality has been reached.

Input field usage reporting

tracks usage. To deduplicate operations, Apollo uses

which denormalize the and inputs. This means that the result of the does not track which on input types are used.

For example, will not be able to track how many times the input GetUsersInput.firstName is used in this schema:

type Query {
getUsers(filters: GetUsersInput): [User]
}
input GetUsersInput {
firstName: String
lastName: String
}
type User {
id: ID!
firstName: String!
lastName: String!
}
Previous
Overview
Next
Configure schema checks
Edit on GitHubEditForumsDiscord

© 2024 Apollo Graph Inc.

Privacy Policy

Company