Structural changes to a GraphQL schema come in two categories:
title
field, anyone who tries to query that field will get a validation error instead of response data.Making a breaking change can be bad news for your API clients, since their applications may break. But, sometimes they’re required. Non-breaking changes don’t affect existing queries, since they just add new parts to the schema.
Here are few tips for managing schema structure changes.
.graphql
schema dumpMake structure changes part of the normal code review process by adding a schema.graphql
artifact to your project. This way, any changes to schema structure will show up clearly in a pull request as a diff to that file.
You can read about this approach in “Tracking Schema Changes with GraphQL-Ruby” or the built-in GraphQL::RakeTask
for generating schema dumps.
You can use GraphQL::SchemaComparator to check for breaking changes during development or CI. If you maintain a dump of queries that typically run against your server, you may also utilize GraphQL::StaticValidation
to validate these queries directly. A Rake task such as the one below can be used to identify changes that are incompatible with existing queries.
namespace :graphql do
namespace :queries do
desc 'Validates GraphQL queries against the current schema'
task validate: [:environment] do
queries_file = 'test/fixtures/files/queries.json'
queries = Oj.load(File.read(queries_file))
Validate.run_validate(queries, MySchema)
end
module Validate
def self.run_validate(queries, schema)
puts '⏳ Validating queries...'
puts "\n"
results = queries.map { |query| schema.validate(query) }
errors = results.flatten
if errors.empty?
puts '✅ All queries are valid'
else
print_errors(errors)
end
end
def self.print_errors(errors)
puts 'Detected the following errors:'
puts "\n"
errors.each do |error|
path = error.path.join(', ')
puts "❌ #{path}: #{error.message}"
end
end
end
end
end