guides/schema/definition.md
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:
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: {% 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" %}.
In development, GraphQL-Ruby can defer loading your type definitions until they're needed. This requires some configuration to opt in:
Add use GraphQL::Schema::Visibility to your schema. ({{ "GraphQL::Schema::Visibility" | api_doc }} supports lazy loading and will be the default in a future GraphQL-Ruby version. See {% internal_link "Migration Notes", "/authorization/visibility#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 {% internal_link "Object Identification", "/schema/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" | api_doc }} 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" | api_doc }}), Argument {% internal_link "loads:", "/mutations/mutation_classes#auto-loading-arguments" %}, or the {% internal_link "ObjectCache", "/object_cache/overview" %}. 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" | api_doc }} 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" | api_doc }} is called by GraphQL-Ruby to get the runtime Object type for fields that return return {% internal_link "interface", "/type_definitions/interfaces" %} or {% internal_link "union", "/type_definitions/unions" %} types.
false during query execution.Parser caching: if your application parses GraphQL files (queries or schema definition), it may benefit from enabling {{ "GraphQL::Language::Cache" | api_doc }}.
Eager loading the library: by default, GraphQL-Ruby autoloads its constants as-needed. In production, they should be eager loaded instead, using GraphQL.eager_load!.
.eager_load!.)configure(:production) { GraphQL.eager_load! } to your application file.environment(:production) { GraphQL.eager_load! } to your application file.GraphQL.eager_load! when your application is booting in production mode.See {{"GraphQL::Autoload#eager_load!" | api_doc }} for more details.