Overview
We could just merge our changes and let GraphOS know about them, but let's take a pause and first validate that these changes won't break anything. We're responsible developers, after all!
In this lesson, we will:
- Learn about the different types of schema checks
- Understand how schema checks fit into the overall process of updating a supergraph
- Run a schema check locally using the Rover CLI
- Inspect the results of a schema check in Studio
What are schema checks?
Schema checks are a set of predefined tests that help identify potential failures caused by schema updates. They check for issues like incompatibilities between subgraph schemas or breaking existing client operations. With schema checks, we can ensure that our schema changes won't cause issues when we deploy to production.
We'll talk about two types of schema checks: build checks and operation checks.
Build checks
Build checks validate that a subgraph's schema changes can still compose successfully with other subgraph schemas in the supergraph.
For example, if a new type is added to one subgraph, a build check determines whether that addition is compatible with the rest of the subgraphs in the supergraph. If it isn't, we need to investigate the error and fix it.
Note: Our Poetic Plates supergraph only has one subgraph (recipes) right now, so build checks aren't too relevant for us at this stage!
Operation checks
Operation checks validate that a schema's changes won't break any operations that existing clients send to the graph.
For example, let's say a web client regularly sends a GraphQL query to retrieve data for its homepage. If a schema change involves adding a required argument to a field in that query, it might break that client's existing operation if it doesn't include that argument! An operation check helps us guard against this potential failure, listing out the affected operations and allowing the team to address them.
Linter checks
Linter checks analyze your proposed schema changes for violations of formatting rules and other GraphQL best practices. GraphOS provides a set of default rules you can configure to suit your team's conventions. You can see a full list of rules in the Apollo documentation.
Some common schema conventions include: writing field names in camelCase
, type names in PascalCase
, and enums in SCREAMING_SNAKE_CASE
.
rover subgraph check
There are two main ways to run schema checks using the Rover CLI. We can run schema checks locally in our terminal (which we'll do shortly). We can also integrate schema checks into our CI pipelines to run automatically against new pull requests (we'll do this in the next lesson).
To perform a schema check for a subgraph, we use the rover subgraph check
command with the following parameters:
rover subgraph check <GRAPH_REF> \--schema <SCHEMA_FILE_PATH> \--name <SUBGRAPH_NAME>
Note: The graph reference (or graph ref) tells Rover about our supergraph. A graph ref starts with the graph's ID, followed by an @
symbol, followed by the graph variant.
This command runs a build check first, then an operation check, then a linter check, and finally outputs the results in the command line. It also reports the results to GraphOS, so we can view them from your graph's Checks page.
Running schema checks
Let's give it a try! We made schema changes by deprecating a field and adding a new field in the previous lesson, so let's make sure those changes are safe before pushing them up to our schema registry.
First let's grab the graph reference for our supergraph. We can find this value in Studio, at the top of the graph's README page.
Next, let's open up a new terminal and paste in the rover subgraph check
command. Make sure you replace the parameters with your own values.
rover subgraph check poetic-plates-supergraph@main \--schema schema.graphql \--name recipes
After the process completes, we can see a report of the schema changes. The terminal output shows the following:
Checking the proposed schema for subgraph recipes against poetic-plates-supergraph@mainCheck Result:Compared 2 schema changes against 123 operations┌────────┬──────────────────┬──────────────────────────────────────────────────────┐│ Change │ Code │ Description │├────────┼──────────────────┼──────────────────────────────────────────────────────┤│ PASS │ FIELD_DEPRECATED │ type `Ingredient`: field `text` deprecated │├────────┼──────────────────┼──────────────────────────────────────────────────────┤│ PASS │ FIELD_ADDED │ type `Ingredient`: field `detailedDescription` added │└────────┴──────────────────┴──────────────────────────────────────────────────────┘View full details at [Studio URL]
The first column indicates whether each change passed or failed the check. The second column indicates the type of change we made, such as FIELD_ADDED
and FIELD_DEPRECATED
. The last column provides a more detailed description of the change, such as what exact type was created and what field was added under the type.
Awesome, we have no errors! We can tell that the checks passed, because each row in the output table has a PASS status. The schema changes were also compared against the number of existing client operations, and no breaking changes were detected.
We can check out the results of this schema check (and any past checks) in Studio too! Rover adds a link to this specific check at the end of its message.
Head over to your supergraph in Studio and navigate to the Checks page. You'll see the same results reflected there.
Optional: A failed check
For fun, let's see what would have happened if one of our checks failed.
Open up the schema.graphql
file and find the text
field we just deprecated, and remove the reason
argument.
text: String @deprecated
In a terminal window, run the schema check again.
rover subgraph check poetic-plates-supergraph@main \--schema schema.graphql \--name recipes
After the process completes, we can see a report of the schema changes. The terminal output shows the following:
Checking the proposed schema for subgraph recipes against poetic-plates-supergraph@mainThere were no changes detected in the composed API schema, but the core schema was modified.Operation Check [PASSED]:Compared 2 schema changes against 120 operations.┌────────┬──────────────────┬──────────────────────────────────────────────────────┐│ Change │ Code │ Description │├────────┼──────────────────┼──────────────────────────────────────────────────────┤│ PASS │ FIELD_DEPRECATED │ type `Ingredient`: field `text` deprecated │├────────┼──────────────────┼──────────────────────────────────────────────────────┤│ PASS │ FIELD_ADDED │ type `Ingredient`: field `detailedDescription` added │└────────┴──────────────────┴──────────────────────────────────────────────────────┘View operation check details at: [Studio URL]Lint Check [PASSED]:Resulted in 1 warning.┌─────────┬─────────────────┬──────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────┐│ Level │ Coordinate │ Line │ Description │├─────────┼─────────────────┼──────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┤│ WARNING │ Ingredient.text │ 1269 │ When applying the @deprecated directive, always include the reason argument: @deprecated(reason: String). │└─────────┴─────────────────┴──────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────┘View lint check details at: [Studio URL]
We can see that our operation checks passed, and so did the linter checks, but with a warning: the @deprecated
directive should always include the reason
argument. We can view the check results in Studio as well.
Note: By default, all linter rules are set to "Warn". To view and change the severity of a rule, click "View Configuration". The full list of rules and their severity can be changed on that page.
Before we forget, let's add the reason
argument back and get our checks passing again!
"Display text for the ingredient"text: String @deprecated(reason: "Use detailedDescription")
Practice
Drag items from this box to the blanks above
Deprecated
Build
Field
Operation
Subgraph
Linter
rover subgraph check
command need?Key takeaways
- Schema checks help identify potential failures caused by schema updates before they can cause issues in production.
- Build checks validate that a subgraph's schema changes can still compose successfully with other subgraph schemas.
- Operation checks validate that a schema's changes won't break any operations that existing clients are sending to the graph.
- Linter checks validate that a schema follows formatting rules and conventions.
- To run a schema check, we use the
rover subgraph check
command. - We can inspect the results of a schema check through the terminal or in the Studio Checks page.
Up next
Using GraphOS tools like Rover and Studio, we've validated that our schema changes are safe and don't break anything! 🎉 It's time to publish our changes to our supergraph's schema registry.
Share your questions and comments about this lesson
Your feedback helps us improve! If you're stuck or confused, let us know and we'll help you out. All comments are public and must follow the Apollo Code of Conduct. Note that comments that have been resolved or addressed may be removed.
You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.