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.
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
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.
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
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
.
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
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
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