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::Dataloader
# 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 methods.
For defining GraphQL types, see the guides for those types: object types, interface types, union types, input object types, enum types, and scalar types.
Schema.query
, Schema.mutation
, and Schema.subscription
declare the entry-point types of the schema.
Schema.orphan_types
declares object types which implement Interfaces but aren’t used as field return types in the schema. For more about this specific scenario, see Orphan Types
In development, GraphQL-Ruby can defer loading your type definitions until they’re needed. This requires some configuration to opt in:
use GraphQL::Schema::Visibility
to your schema. (GraphQL::Schema::Visibility
supports lazy loading and will be the default in a future GraphQL-Ruby version. See Migration Notes if you have an existing visibility implementation.)Move your entry-point type definitions into a block, for example:
- query Types::Query
+ query { Types::Query }
Optionally, move field types into blocks, too:
- field :posts, [Types::Post] # Loads `types/post.rb` immediately
+ field :posts do
+ type([Types::Post]) # Loads `types/post.rb` when this field is used in a query
+ end
To enforce these patterns, you can enable two Rubocop rules that ship with GraphQL-Ruby:
GraphQL/RootTypesInBlock
will make sure that query
, mutation
, and subscription
are all defined in a block.GraphQL/FieldTypeInBlock
will make sure that non-built-in field return types are defined in blocks.Some GraphQL features use unique IDs to load objects:
node(id:)
field looks up objects by ID (See Object Identification for more about Relay-style object identification.)loads:
configurations look up objects by IDTo use these features, you must provide some methods for generating UUIDs and fetching objects with them:
Schema.object_from_id
is called by GraphQL-Ruby to load objects directly from the database. It’s usually used by the node(id: ID!): Node
field (see GraphQL::Types::Relay::Node
), Argument loads:, or the ObjectCache. 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).
Schema.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.
Additionally, Schema.resolve_type
is called by GraphQL-Ruby to get the runtime Object type for fields that return return interface or union types.
Schema.type_error
handles type errors at runtime, read more in the Type errors guide.
Schema.rescue_from
defines error handlers for application errors. See the error handling guide for more.
Schema.parse_error
and Schema.query_stack_error
provide hooks for reporting errors to your bug tracker.
Schema.max_depth
and Schema.max_complexity
apply some limits to incoming queries. See Complexity and Depth for more.
Schema.default_max_page_size
applies limits to connection fields.
Schema.validate_timeout
, Schema.validate_max_errors
and Schema.max_query_string_tokens
all apply limits to query execution. See Timeout for more.
Schema.extra_types
declares types which should be printed in the SDL and returned in introspection queries, but aren’t otherwise used in the schema.
Schema.introspection
can attach a custom introspection system to the schema.
Schema.unauthorized_object
and Schema.unauthorized_field
are called when authorization hooks return false
during query execution.
Schema.trace_with
attaches tracer modules. See Tracing for more.
Schema.query_analyzer
and Schema.multiplex_analyzer accept processors for ahead-of-time query analysis, see Analysis for more.
Schema.default_logger
configures a logger for runtime. See Logging.
Schema.context_class
and Schema.query_class
attach custom subclasses to your schema to use during execution.
Schema.lazy_resolve
registers classes with lazy execution.
Schema.use
adds plugins to your schema. For example, GraphQL::Dataloader
and GraphQL::Schema::Visibility
are installed this way.