GraphQL-Ruby includes a way to build a runable schema from the GraphQL Schema Definition Language (SDL). GraphQL::Schema.from_definition returns a schema class based on a filename or string containing GraphQL SDL. For example:
# From a file:
MySchema = GraphQL::Schema.from_definition("path/to/schema.graphql")
# Or, from a string:
MySchema = GraphQL::Schema.from_definition(<<~GRAPHQL)
type Query {
# ...
}
# ...
GRAPHQL
Definitions from the SDL are converted into Ruby classes, similar to those defined in plain Ruby code.
You can provide execution behaviors to a generated schema as default_resolve:, which accepts two kinds of values:
By providing an object that implements several runtime methods, you can define the execution behaviors of a schema loaded from SDL:
class SchemaImplementation
# see below for methods
end
# Pass the object as `default_resolve:`
MySchema = GraphQL::Schema.from_definition(
"path/to/schema.graphql",
default_resolve: SchemaImplementation.new
)
The default_resolve: object may implement:
#call(type, field, obj, args, ctx) for resolving fields#resolve_type(abstract_type, obj, ctx) for resolving obj as one of abstract_type’s possible object types#coerce_input(type, value, ctx) for coercing scalar input#coerce_result(type, value, ctx) for coercing scalar return valuesAlternatively, you can provide a Hash containing callable behaviors, for example:
schema_implementation = {
# ... see below for hash structure
}
# Pass the hash as `default_resolve:`
MySchema = GraphQL::Schema.from_definition(
"path/to/schema.graphql",
default_resolve: schema_implementation
)
The hash may contain:
{ field_name => ->(obj, args, ctx) { ... } } for resolving object fields"coerce_result" and "coerce_input", each pointing to a ->(value, ctx) { ... } for handling scalar values at runtime"resolve_type" key pointing to a ->(abstract_type, object, ctx) { ... } callable, used for resolving object to one of abstract_type’s possible typesGraphQL::Schema.from_definition accepts a using: argument, which may be given as a map of plugin => args pairs. For example:
MySchema = GraphQL::Schema.from_definition("path/to/schema.graphql", using: {
GraphQL::Pro::PusherSubscriptions => { redis: $redis },
GraphQL::Pro::OperationStore => nil, # no options here
})
Although GraphQL-Ruby doesn’t have special handling for directives in the SDL, you can build custom behavior in your own app. If part of the schema had a directive, you can access it using .ast_node.directives. For example:
schema = GraphQL::Schema.from_definition <<-GRAPHQL
type Query @flagged {
secret: Boolean @privacy(secret: true)
}
GRAPHQL
pp schema.query.ast_node.directives.map(&:to_query_string)
# => ["@flagged"]
pp schema.get_field("Query", "secret").ast_node.directives.map(&:to_query_string)
# => ["@privacy(secret: true)"]
See GraphQL::Language::Nodes::Directive for available methods.