1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
---
layout: guide
doc_stub: false
search: true
section: Schema
title: Definition
desc: Defining your schema
index: 1
---
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 {% internal_link "introspection system","/schema/introspection" %}.
Your GraphQL schema is a class that extends {{ "GraphQL::Schema" | api_doc }}, for example:
```ruby
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:
- [root objects, introspection and orphan types](#root-objects-introspection-and-orphan-types)
- [object identification hooks](#object-identification-hooks)
- [execution configuration](#execution-configuration)
- [context class](#context-class)
- [default limits](#default-limits)
- [plugins](#plugins)
For defining GraphQL types, see the guides for those types: {% internal_link "object types", "/type_definitions/objects" %}, {% internal_link "interface types", "/type_definitions/interfaces" %}, {% internal_link "union types", "/type_definitions/unions" %}, {% internal_link "input object types", "/type_definitions/input_objects" %}, {% internal_link "enum types", "/type_definitions/enums" %}, and {% internal_link "scalar types", "/type_definitions/scalars" %}.
## 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](https://graphql.org/learn/schema/#the-query-and-mutation-types). Each one is an object type which can be connected to the schema by a method with the same name:
```ruby
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 {% internal_link "customize it","/schema/introspection" %} and hook it up with `introspection`:
```ruby
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 {% internal_link "Orphan Types", "/type_definitions/interfaces#orphan-types" %}.
```ruby
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 {% internal_link "interface", "/type_definitions/interfaces" %} or {% internal_link "union", "/type_definitions/unions" %} types. The class method `def self.resolve_type` is used:
```ruby
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 {% internal_link "Object Identification guide", "/schema/object_identification" %} for more information about these methods.
## Execution Configuration
__`trace_with`__ attaches tracer modules, see {% internal_link "Tracing", "/queries/tracing" %} for more.
```ruby
class MySchema < GraphQL::Schema
trace_with MetricTracer
end
```
__`query_analyzer`__ and __`multiplex_analyzer`__ accept processors for ahead-of-time query analysis, see {% internal_link "Analysis", "/queries/ast_analysis" %} for more.
```ruby
class MySchema < GraphQL::Schema
query_analyzer MyQueryAnalyzer
end
```
__`lazy_resolve`__ registers classes with {% internal_link "lazy execution", "/schema/lazy_execution" %}:
```ruby
class MySchema < GraphQL::Schema
lazy_resolve Promise, :sync
end
```
__`type_error`__ handles type errors at runtime, read more in the {% internal_link "Type errors guide", "/errors/type_errors" %}.
```ruby
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:
```ruby
class MySchema < GraphQL::Schema
rescue_from(ActiveRecord::RecordNotFound) { "Not found" }
end
```
## Context Class
Usually, `context` is an instance of {{ "GraphQL::Query::Context" | api_doc }}, but you can create a custom subclass and attach it with `.context_class`, for example:
```ruby
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 {% internal_link "Complexity and Depth", "/queries/complexity_and_depth" %} for more.
`default_max_page_size` applies limits to `Connection` fields.
```ruby
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 {% internal_link "monitoring tools", "/queries/tracing#monitoring" %} are plugins:
```ruby
class MySchema < GraphQL::Schema
use(GraphQL::Tracing::NewRelicTracing)
end
```
## Extra Types
Documentation-only types can be attached to the schema using {{ "Schema.extra_types" | api_doc }}. Types passed to this method will _always_ be available in introspection queries and SDL print-outs.
```ruby
class MySchema < GraphQL::Schema
# These aren't for queries, but will appear in documentation:
extra_types SystemErrorType, RateLimitExceptionType
end
```
|