Definition

A GraphQL system is called a schema. The schema contains all the types and fields in the system. The schema executes queries and publishes an introspection system.

Your GraphQL schema is a class that extends GraphQL::Schema, for example:

class MyAppSchema < GraphQL::Schema
  max_complexity 400
  query Types::Query
  use GraphQL::Batch

  # Define hooks as class methods:
  def self.resolve_type(type, obj, ctx)
    # ...
  end

  def self.object_from_id(node_id, ctx)
    # ...
  end

  def self.id_from_object(object, type, ctx)
    # ...
  end
end

There are lots of schema configuration options:

For defining GraphQL types, see the guides for those types: object types, interface types, union types, input object types, enum types, and scalar types.

Root Objects, Introspection and Orphan Types

A GraphQL schema is a web of interconnected types, and it has a few starting points for discovering the elements of that web:

Root types (query, mutation, and subscription) are the entry points for queries to the system. Each one is an object type which can be connected to the schema by a method with the same name:

class MySchema < GraphQL::Schema
  # Required:
  query Types::Query
  # Optional:
  mutation Types::Mutation
  subscription Types::Subscription
end

Introspection is a built-in part of the schema. Every schema has a default introspection system, but you can customize it and hook it up with introspection:

class MySchema < GraphQL::Schema
  introspection CustomIntrospection
end

Orphan Types are types which should be in the schema, but can’t be discovered by traversing the types and fields from query, mutation or subscription. This has one very specific use case, see Orphan Types.

class MySchema < GraphQL::Schema
  orphan_types [Types::Comment, ...]
end

Object Identification Hooks

A GraphQL schema needs a handful of hooks for finding and disambiguating objects while queries are executed.

resolve_type is used when a specific object’s corresponding GraphQL type must be determined. This happens for fields that return interface or union types. The class method def self.resolve_type is used:

class MySchema < GraphQL::Schema
  def self.resolve_type(abstract_type, object, context)
    # Disambiguate `object`, from among `abstract_type`'s members
    # (`abstract_type` is an interface or union type.)
  end
end

resolve_type is also used by loads: to confirm that loaded objects match the configured type.

object_from_id is used by the node(id: ID!): Node field and loads: configuration. It receives a unique ID and must return the object for that ID, or nil if the object isn’t found (or if it should be hidden from the current user). id_from_object is used to implement Node.id. It should return a unique ID for the given object. This ID will later be sent to object_from_id to refetch the object.

See the Object Identification guide for more information about these methods.

Execution Configuration

trace_with attaches tracer modules, see Tracing for more.

class MySchema < GraphQL::Schema
  trace_with MetricTracer
end

query_analyzer and multiplex_analyzer accept processors for ahead-of-time query analysis, see Analysis for more.

class MySchema < GraphQL::Schema
  query_analyzer MyQueryAnalyzer
end

lazy_resolve registers classes with lazy execution:

class MySchema < GraphQL::Schema
  lazy_resolve Promise, :sync
end

type_error handles type errors at runtime, read more in the Type errors guide.

class MySchema < GraphQL::Schema
  def self.type_error(type_err, context)
    # Handle `type_err` in some way
  end
end

rescue_from accepts error handlers for application errors, for example:

class MySchema < GraphQL::Schema
  rescue_from(ActiveRecord::RecordNotFound) { "Not found" }
end

Context Class

Usually, context is an instance of GraphQL::Query::Context, but you can create a custom subclass and attach it with .context_class, for example:

class CustomContext < GraphQL::Query::Context
  # Shorthand to get the current user
  def viewer
    self[:viewer]
  end
end

class MySchema < GraphQL::Schema
  context_class CustomContext
end

Then, during execution, context will be an instance of CustomContext.

Default Limits

max_depth and max_complexity apply some limits to incoming queries. See Complexity and Depth for more.

default_max_page_size applies limits to Connection fields.

class MySchema < GraphQL::Schema
  max_depth 15
  max_complexity 300
  default_max_page_size 20
end

Plugins

A plugin is an object that responds to #use. Plugins are used to attach new behavior to a schema without a lot of API overhead. For example, the gem’s monitoring tools are plugins:

class MySchema < GraphQL::Schema
  use(GraphQL::Tracing::NewRelicTracing)
end

Extra Types

Documentation-only types can be attached to the schema using Schema.extra_types. Types passed to this method will always be available in introspection queries and SDL print-outs.

class MySchema < GraphQL::Schema
  # These aren't for queries, but will appear in documentation:
  extra_types SystemErrorType, RateLimitExceptionType
end