graphql-doctor

graphql-doctor maps GraphQL-Ruby's runtime schema back to Prism-parsed Ruby source and checks resolver contracts before a query reaches production.

Installation

Add it to the application that owns the schema:

group :development, :test do
  gem "graphql-doctor"
end

The gem supports Ruby 3.1+ and GraphQL-Ruby 2.0+. GraphQL-Ruby 2.0.0 itself cannot build interface schemas on Ruby 3.4, so use 2.0.32 or newer for that combination. The gem's only runtime dependency is Prism.

Configuration

Create .graphql-doctor.yml in the application root:

schema: MyAppSchema
require: ./config/environment
include:
  - app/graphql/**/*.rb
exclude:
  - app/graphql/legacy/**/*.rb

checks:
  GQLD201: { severity: warning }
  GQLD305: { enabled: true }

allow_underlying_object:
  - Types::UserType
abstract_classes:
  - Mutations::BaseMutation

Commands

bundle exec graphql-doctor check
bundle exec graphql-doctor check app/graphql --format github
bundle exec graphql-doctor dump-schema --out tmp/schema.json
bundle exec graphql-doctor check --no-boot --schema-dump tmp/schema.json
bundle exec graphql-doctor coverage
bundle exec graphql-doctor explain GQLD301

check exits with 0 when the configured threshold is clear, 1 for diagnostics at or above --fail-level, and 2 for configuration or boot failures. Formats are text, json, sarif, and github. NO_COLOR and --no-color disable ANSI output.

For CI split boot from checking by passing the output of dump-schema to --schema-dump. Cache files are stored under .graphql-doctor/cache; add .graphql-doctor/ to the target application's .gitignore.

Suppression

Suppress one line or a whole file:

def resolve(id:) # graphql-doctor:disable GQLD301 -- handled by an extension
# graphql-doctor:disable-file GQLD201 -- objects provide all fields

Set require_suppression_reason: true to ignore suppression comments without trailing reasons.

Development

Run bundle exec rake test. See diagnostic references for causes and fixes.

License

MIT. See LICENSE.txt.