Class: GraphQL::Schema
- Inherits:
-
Object
- Object
- GraphQL::Schema
- Includes:
- Define::InstanceDefinable, BuildFromDefinition
- Defined in:
- lib/graphql/schema.rb,
lib/graphql/schema/loader.rb,
lib/graphql/schema/warden.rb,
lib/graphql/schema/printer.rb,
lib/graphql/schema/type_map.rb,
lib/graphql/schema/validation.rb,
lib/graphql/schema/reduce_types.rb,
lib/graphql/schema/possible_types.rb,
lib/graphql/schema/type_expression.rb,
lib/graphql/schema/middleware_chain.rb,
lib/graphql/schema/rescue_middleware.rb,
lib/graphql/schema/invalid_type_error.rb,
lib/graphql/schema/timeout_middleware.rb,
lib/graphql/schema/unique_within_type.rb,
lib/graphql/schema/catchall_middleware.rb,
lib/graphql/schema/build_from_definition.rb,
lib/graphql/schema/instrumented_field_map.rb
Overview
A GraphQL schema which may be queried with Query.
The Schema contains:
- types for exposing your application
- query analyzers for assessing incoming queries (including max depth & max complexity restrictions)
- execution strategies for running incoming queries
- middleware for interacting with execution
Schemas start with root types, Schema#query, Schema#mutation and Schema#subscription.
The schema will traverse the tree of fields & types, using those as starting points.
Any undiscoverable types may be provided with the types
configuration.
Schemas can restrict large incoming queries with max_depth
and max_complexity
configurations.
(These configurations can be overridden by specific calls to #execute)
Schemas can specify how queries should be executed against them.
query_execution_strategy
, mutation_execution_strategy
and subscription_execution_strategy
each apply to corresponding root types.
A schema accepts a Relay::GlobalNodeIdentification
instance for use with Relay IDs.
Defined Under Namespace
Modules: BuildFromDefinition, CatchallMiddleware, Loader, Printer, ReduceTypes, TypeExpression, UniqueWithinType Classes: InstrumentedFieldMap, InvalidTypeError, MiddlewareChain, PossibleTypes, RescueMiddleware, TimeoutMiddleware, TypeMap, Validation, Warden
Constant Summary collapse
- BUILT_IN_TYPES =
- DIRECTIVES =
[GraphQL::Directive::IncludeDirective, GraphQL::Directive::SkipDirective, GraphQL::Directive::DeprecatedDirective]
- DYNAMIC_FIELDS =
["__type", "__typename", "__schema"]
Instance Attribute Summary collapse
-
#id_from_object_proc ⇒ Object
readonly
Returns the value of attribute id_from_object_proc.
-
#middleware ⇒ Array<#call>
readonly
Middlewares suitable for MiddlewareChain, applied to fields during execution.
-
#object_from_id_proc ⇒ Object
readonly
Returns the value of attribute object_from_id_proc.
-
#resolve_type_proc ⇒ Object
readonly
Returns the value of attribute resolve_type_proc.
-
#static_validator ⇒ Object
readonly
Returns the value of attribute static_validator.
-
#types ⇒ GraphQL::Schema::TypeMap
readonly
{ name => type }
pairs of types in this schema.
Class Method Summary collapse
-
.from_introspection(introspection_result) ⇒ GraphQL::Schema
Create schema with the result of an introspection query.
Instance Method Summary collapse
- #define(**kwargs, &block) ⇒ Object
-
#execute(*args) ⇒ Hash
Execute a query on itself.
- #execution_strategy_for_operation(operation) ⇒ Object
-
#get_field(parent_type, field_name) ⇒ GraphQL::Field?
Resolve field named
field_name
for typeparent_type
. -
#id_from_object(object, type, ctx) ⇒ String
Get a unique identifier from this object.
- #id_from_object=(new_proc) ⇒ Object
-
#initialize ⇒ Schema
constructor
A new instance of Schema.
-
#object_from_id(id, ctx) ⇒ Any
Fetch an application object by its unique id.
- #object_from_id=(new_proc) ⇒ Object
-
#possible_types(type_defn) ⇒ Array<GraphQL::ObjectType>
Types which belong to
type_defn
in this schema. - #remove_handler(*args, &block) ⇒ Object
- #rescue_from(*args, &block) ⇒ Object
-
#resolve_type(object, ctx) ⇒ GraphQL::ObjectType
Determine the GraphQL type for a given object.
- #resolve_type=(new_resolve_type_proc) ⇒ Object
- #root_type_for_operation(operation) ⇒ Object
- #type_from_ast(ast_node) ⇒ Object
Methods included from Define::InstanceDefinable
Constructor Details
#initialize ⇒ Schema
Returns a new instance of Schema.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/graphql/schema.rb', line 85 def initialize @orphan_types = [] @directives = DIRECTIVES.reduce({}) { |m, d| m[d.name] = d; m } @static_validator = GraphQL::StaticValidation::Validator.new(schema: self) @middleware = [] @query_analyzers = [] @resolve_type_proc = nil @object_from_id_proc = nil @id_from_object_proc = nil @instrumenters = Hash.new { |h, k| h[k] = [] } # Default to the built-in execution strategy: @query_execution_strategy = GraphQL::Query::SerialExecution @mutation_execution_strategy = GraphQL::Query::SerialExecution @subscription_execution_strategy = GraphQL::Query::SerialExecution end |
Instance Attribute Details
#id_from_object_proc ⇒ Object (readonly)
Returns the value of attribute id_from_object_proc.
75 76 77 |
# File 'lib/graphql/schema.rb', line 75 def id_from_object_proc @id_from_object_proc end |
#middleware ⇒ Array<#call> (readonly)
Returns Middlewares suitable for MiddlewareChain, applied to fields during execution.
|
# File 'lib/graphql/schema.rb', line 77
|
#object_from_id_proc ⇒ Object (readonly)
Returns the value of attribute object_from_id_proc.
75 76 77 |
# File 'lib/graphql/schema.rb', line 75 def object_from_id_proc @object_from_id_proc end |
#resolve_type_proc ⇒ Object (readonly)
Returns the value of attribute resolve_type_proc.
75 76 77 |
# File 'lib/graphql/schema.rb', line 75 def resolve_type_proc @resolve_type_proc end |
#static_validator ⇒ Object (readonly)
Returns the value of attribute static_validator.
75 76 77 |
# File 'lib/graphql/schema.rb', line 75 def static_validator @static_validator end |
#types ⇒ GraphQL::Schema::TypeMap (readonly)
Returns { name => type }
pairs of types in this schema.
139 140 141 |
# File 'lib/graphql/schema.rb', line 139 def types @types end |
Class Method Details
.from_introspection(introspection_result) ⇒ GraphQL::Schema
Create schema with the result of an introspection query.
280 281 282 |
# File 'lib/graphql/schema.rb', line 280 def self.from_introspection(introspection_result) GraphQL::Schema::Loader.load(introspection_result) end |
Instance Method Details
#define(**kwargs, &block) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/graphql/schema.rb', line 111 def define(**kwargs, &block) super all_types = orphan_types + [query, mutation, subscription, GraphQL::Introspection::SchemaType] @types = GraphQL::Schema::ReduceTypes.reduce(all_types.compact) @instrumented_field_map = InstrumentedFieldMap.new(self) field_instrumenters = @instrumenters[:field] types.each do |type_name, type| if type.kind.fields? type.all_fields.each do |field_defn| instrumented_field_defn = field_instrumenters.reduce(field_defn) do |defn, inst| inst.instrument(type, defn) end @instrumented_field_map.set(type.name, field_defn.name, instrumented_field_defn) end end end # Assert that all necessary configs are present: validation_error = Validation.validate(self) validation_error && raise(NotImplementedError, validation_error) nil end |
#execute(*args) ⇒ Hash
Execute a query on itself. See Query#initialize for arguments.
144 145 146 147 |
# File 'lib/graphql/schema.rb', line 144 def execute(*args) query_obj = GraphQL::Query.new(self, *args) query_obj.result end |
#execution_strategy_for_operation(operation) ⇒ Object
196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/graphql/schema.rb', line 196 def execution_strategy_for_operation(operation) case operation when "query" query_execution_strategy when "mutation" mutation_execution_strategy when "subscription" subscription_execution_strategy else raise ArgumentError, "unknown operation type: #{operation}" end end |
#get_field(parent_type, field_name) ⇒ GraphQL::Field?
Resolve field named field_name
for type parent_type
.
Handles dynamic fields __typename
, __type
and __schema
, too
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/graphql/schema.rb', line 153 def get_field(parent_type, field_name) ensure_defined defined_field = @instrumented_field_map.get(parent_type.name, field_name) if defined_field defined_field elsif field_name == "__typename" GraphQL::Introspection::TypenameField.create(parent_type) elsif field_name == "__schema" && parent_type == query GraphQL::Introspection::SchemaField.create(self) elsif field_name == "__type" && parent_type == query GraphQL::Introspection::TypeByNameField.create(self) else nil end end |
#id_from_object(object, type, ctx) ⇒ String
Get a unique identifier from this object
262 263 264 265 266 267 268 269 |
# File 'lib/graphql/schema.rb', line 262 def id_from_object(object, type, ctx) ensure_defined if @id_from_object_proc.nil? raise(NotImplementedError, "Can't generate an ID for #{object.inspect} of type #{type}, schema's `id_from_object` must be defined") else @id_from_object_proc.call(object, type, ctx) end end |
#id_from_object=(new_proc) ⇒ Object
272 273 274 275 |
# File 'lib/graphql/schema.rb', line 272 def id_from_object=(new_proc) ensure_defined @id_from_object_proc = new_proc end |
#object_from_id(id, ctx) ⇒ Any
Fetch an application object by its unique id
242 243 244 245 246 247 248 249 |
# File 'lib/graphql/schema.rb', line 242 def object_from_id(id, ctx) ensure_defined if @object_from_id_proc.nil? raise(NotImplementedError, "Can't fetch an object for id \"#{id}\" because the schema's `object_from_id (id, ctx) -> { ... }` function is not defined") else @object_from_id_proc.call(id, ctx) end end |
#object_from_id=(new_proc) ⇒ Object
252 253 254 255 |
# File 'lib/graphql/schema.rb', line 252 def object_from_id=(new_proc) ensure_defined @object_from_id_proc = new_proc end |
#possible_types(type_defn) ⇒ Array<GraphQL::ObjectType>
Returns types which belong to type_defn
in this schema.
177 178 179 180 181 |
# File 'lib/graphql/schema.rb', line 177 def possible_types(type_defn) ensure_defined @possible_types ||= GraphQL::Schema::PossibleTypes.new(self) @possible_types.possible_types(type_defn) end |
#remove_handler(*args, &block) ⇒ Object
106 107 108 109 |
# File 'lib/graphql/schema.rb', line 106 def remove_handler(*args, &block) ensure_defined rescue_middleware.remove_handler(*args, &block) end |
#rescue_from(*args, &block) ⇒ Object
101 102 103 104 |
# File 'lib/graphql/schema.rb', line 101 def rescue_from(*args, &block) ensure_defined rescue_middleware.rescue_from(*args, &block) end |
#resolve_type(object, ctx) ⇒ GraphQL::ObjectType
Determine the GraphQL type for a given object.
This is required for unions and interfaces (including Relay's Node
interface)
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/graphql/schema.rb', line 215 def resolve_type(object, ctx) ensure_defined if @resolve_type_proc.nil? raise(NotImplementedError, "Can't determine GraphQL type for: #{object.inspect}, define `resolve_type (obj, ctx) -> { ... }` inside `Schema.define`.") end type_result = @resolve_type_proc.call(object, ctx) if type_result.nil? nil elsif !type_result.is_a?(GraphQL::BaseType) type_str = "#{type_result} (#{type_result.class.name})" raise "resolve_type(#{object}) returned #{type_str}, but it should return a GraphQL type" else type_result end end |
#resolve_type=(new_resolve_type_proc) ⇒ Object
233 234 235 236 |
# File 'lib/graphql/schema.rb', line 233 def resolve_type=(new_resolve_type_proc) ensure_defined @resolve_type_proc = new_resolve_type_proc end |
#root_type_for_operation(operation) ⇒ Object
183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/graphql/schema.rb', line 183 def root_type_for_operation(operation) case operation when "query" query when "mutation" mutation when "subscription" subscription else raise ArgumentError, "unknown operation type: #{operation}" end end |
#type_from_ast(ast_node) ⇒ Object
169 170 171 172 |
# File 'lib/graphql/schema.rb', line 169 def type_from_ast(ast_node) ensure_defined GraphQL::Schema::TypeExpression.build_type(self.types, ast_node) end |