class GraphQL::Schema::Resolver
A class-based container for field configuration and resolution logic. It supports:
-
Arguments, via
.argument(...)helper, which will be applied to the field. -
Return type, via
.type(..., null: ...), which will be applied to the field. -
Description, via
.description(...), which will be applied to the field -
Comment, via
.comment(...), which will be applied to the field -
Resolution, via
resolve(**args)method, which will be called to resolve the field.
Resolvers can be attached with the resolver: option in a field(...) call.
A resolver’s configuration may be overridden with other keywords in the field(...) call.
See GraphQL::Schema::Mutation for a concrete subclass of Resolver. Resolver is a replacement for the former GraphQL::Function API.
Attributes
Returns
Returns
Returns
-
Object— The application object this field is being resolved on
Public Class Methods
# File lib/graphql/schema/resolver.rb, line 352 def all_field_argument_definitions all_argument_definitions end
Source
# File lib/graphql/schema/resolver.rb, line 344 def any_field_arguments? any_arguments? end
# File lib/graphql/schema/resolver.rb, line 553 def argument(*args, **kwargs, &block) # Use `from_resolver: true` to short-circuit the InputObject's own `loads:` implementation # so that we can support `#load_{x}` methods below. args = args #: untyped super(*args, from_resolver: true, **kwargs) end
Add an argument to this field’s signature, but also add some preparation hook methods which will be used for this argument See GraphQL::Schema::Argument for the signature
# File lib/graphql/schema/resolver.rb, line 457 def broadcastable(new_broadcastable) @broadcastable = new_broadcastable end
# File lib/graphql/schema/resolver.rb, line 467 def broadcastable? if defined?(@broadcastable) @broadcastable else (superclass.respond_to?(:broadcastable?) ? superclass.broadcastable? : nil) end end
Returns
-
Boolean, nil
# File lib/graphql/schema/resolver.rb, line 450 def complexity(new_complexity = nil) if new_complexity @complexity = new_complexity end @complexity || (superclass.respond_to?(:complexity) ? superclass.complexity : 1) end
Specifies the complexity of the field. Defaults to 1
Returns
-
Integer, Proc
# File lib/graphql/schema/resolver.rb, line 523 def default_page_size(new_default_page_size = NOT_CONFIGURED) if new_default_page_size != NOT_CONFIGURED @default_page_size = new_default_page_size elsif defined?(@default_page_size) @default_page_size elsif superclass.respond_to?(:default_page_size) superclass.default_page_size else nil end end
Get or set the default_page_size: which will be configured for fields using this resolver (nil means “unlimited default page size”.)
Parameters
-
default_page_size(Integer, nil) — Set a new value
Returns
-
Integer, nil— Thedefault_page_sizeassigned to fields that use this resolver
# File lib/graphql/schema/resolver.rb, line 569 def extension(extension, **options) @own_extensions ||= [] @own_extensions << {extension => options} end
Registers new extension
Parameters
-
extension(Class) — Extension class -
options(Hash) — Optional extension options
Source
# File lib/graphql/schema/resolver.rb, line 373 def extras(new_extras = nil) if new_extras @own_extras = new_extras end own_extras = @own_extras || [] own_extras + (superclass.respond_to?(:extras) ? superclass.extras : []) end
Additional info injected into resolve See GraphQL::Schema::Field#extras
# File lib/graphql/schema/resolver.rb, line 340 def field_arguments(context = GraphQL::Query::NullContext.instance) arguments(context) end
# File lib/graphql/schema/resolver.rb, line 348 def get_field_argument(name, context = GraphQL::Query::NullContext.instance) get_argument(name, context) end
# File lib/graphql/schema/resolver.rb, line 541 def has_default_page_size? (!!defined?(@default_page_size)) || (superclass.respond_to?(:has_default_page_size?) && superclass.has_default_page_size?) end
Returns
-
Boolean—trueif this resolver or a superclass has an assigneddefault_page_size
Source
# File lib/graphql/schema/resolver.rb, line 506 def has_max_page_size? (!!defined?(@max_page_size)) || (superclass.respond_to?(:has_max_page_size?) && superclass.has_max_page_size?) end
Returns
-
Boolean—trueif this resolver or a superclass has an assignedmax_page_size
Source
# File lib/graphql/schema/resolver.rb, line 593 def inherited(child_class) child_class.description(description) super end
# File lib/graphql/schema/resolver.rb, line 488 def max_page_size(new_max_page_size = NOT_CONFIGURED) if new_max_page_size != NOT_CONFIGURED @max_page_size = new_max_page_size elsif defined?(@max_page_size) @max_page_size elsif superclass.respond_to?(:max_page_size) superclass.max_page_size else nil end end
Get or set the max_page_size: which will be configured for fields using this resolver (nil means “unlimited max page size”.)
Parameters
-
max_page_size(Integer, nil) — Set a new value
Returns
-
Integer, nil— Themax_page_sizeassigned to fields that use this resolver
# File lib/graphql/schema/resolver.rb, line 43 def initialize(object:, context:, field:) @object = object @context = context @field = field # Since this hash is constantly rebuilt, cache it for this call @arguments_by_keyword = {} context.types.arguments(self.class).each do |arg| @arguments_by_keyword[arg.keyword] = arg end @prepared_arguments = nil end
Parameters
-
object(Object) — The application object that this field is being resolved on -
context(GraphQL::Query::Context) -
field(GraphQL::Schema::Field)
Source
# File lib/graphql/schema/resolver.rb, line 392 def null(allow_null = nil) if !allow_null.nil? @null = allow_null end @null.nil? ? (superclass.respond_to?(:null) ? superclass.null : true) : @null end
If true (default), then the return type for this resolver will be nullable. If false, then the return type is non-null.
See type which sets the return type of this field and accepts a null: option
Parameters
-
allow_null(Boolean) — Whether or not the response can be null
# File lib/graphql/schema/resolver.rb, line 364 def resolve_method(new_method = nil) if new_method @resolve_method = new_method end @resolve_method || (superclass.respond_to?(:resolve_method) ? superclass.resolve_method : :resolve) end
Default :resolve set below.
Returns
-
Symbol— The method to call on instances of this object to resolve the field
# File lib/graphql/schema/resolver.rb, line 400 def resolver_method(new_method_name = nil) if new_method_name @resolver_method = new_method_name else @resolver_method || :resolve_with_support end end
# File lib/graphql/schema/resolver.rb, line 424 def type(new_type = nil, null: nil) if new_type if null.nil? raise ArgumentError, "required argument `null:` is missing" end @type_expr = new_type @null = null else if type_expr GraphQL::Schema::Member::BuildType.parse_type(type_expr, null: self.null) elsif superclass.respond_to?(:type) superclass.type else nil end end end
Call this method to get the return type of the field, or use it as a configuration method to assign a return type instead of generating one. TODO unify with null
Parameters
-
new_type(Class, Array<Class>, nil) — If a type definition class is provided, it will be used as the return type of the field -
null(true, false) — Whether or not the field may returnnil
Returns
-
Class— The type which this field returns.
Source
# File lib/graphql/schema/resolver.rb, line 546 def type_expr @type_expr || (superclass.respond_to?(:type_expr) ? superclass.type_expr : nil) end
A non-normalized type configuration, without null applied
Public Instance Methods
Source
# File lib/graphql/schema/resolver.rb, line 140 def arguments @prepared_arguments || raise("Arguments have not been prepared yet, still waiting for #load_arguments to resolve. (Call `.arguments` later in the code.)") end
Source
# File lib/graphql/schema/resolver.rb, line 74 def call q = context.query trace_objs = [object] q.current_trace.begin_execute_field(field, @prepared_arguments, trace_objs, q) is_ready = ready?(**@prepared_arguments) runner = @field_resolve_step.runner if runner.resolves_lazies && runner.schema.lazy?(is_ready) is_ready, new_return_value = runner.schema.sync_lazy(is_ready) end if is_ready.is_a?(Array) is_ready, new_return_value = is_ready if is_ready != false raise "Unexpected result from #ready? (expected `true`, `false` or `[false, {...}]`): [#{is_ready.inspect}, #{new_return_value.inspect}]" else new_return_value end end if is_ready begin is_authed, new_return_value = authorized?(**@prepared_arguments) rescue GraphQL::UnauthorizedError => err new_return_value = q.schema.unauthorized_object(err) is_authed = false end end if runner.resolves_lazies && runner.schema.lazy?(is_authed) is_authed, new_return_value = runner.schema.sync_lazy(is_authed) end result = if is_authed Schema::Validator.validate!(self.class.validators, object, context, @prepared_arguments, as: @field) call_resolve(@prepared_arguments) elsif new_return_value.nil? err = UnauthorizedFieldError.new(object: object, type: @field_resolve_step.parent_type, context: context, field: @field) context.schema.unauthorized_field(err) else new_return_value end q = context.query q.current_trace.end_execute_field(field, @prepared_arguments, trace_objs, q, [result]) exec_result[exec_index] = result rescue GraphQL::UnauthorizedError => auth_err exec_result[exec_index] = begin context.schema.unauthorized_object(auth_err) rescue GraphQL::ExecutionError => exec_err exec_err end rescue GraphQL::RuntimeError => err exec_result[exec_index] = err rescue StandardError => stderr exec_result[exec_index] = begin context.query.handle_or_reraise(stderr) rescue GraphQL::ExecutionError => ex_err ex_err end ensure field_pending_steps = field_resolve_step.pending_steps field_pending_steps.delete(self) if field_pending_steps.size == 0 && field_resolve_step.field_results field_resolve_step.runner.add_step(field_resolve_step) end end
# File lib/graphql/schema/resolver.rb, line 238 def ready?(**args) true end
Called before arguments are prepared. Implement this hook to make checks before doing any work.
If it returns a lazy object (like a promise), it will be synced by GraphQL (but the resulting value won’t be used).
Parameters
-
args(Hash) — The input arguments, if there are any
Raises
-
GraphQL::ExecutionError— To add an error to the response -
GraphQL::UnauthorizedError— To signal an authorization failure
Returns
-
Boolean, early_return_data— Iffalse, execution will stop (andearly_return_datawill be returned instead, if present.)
Source
# File lib/graphql/schema/resolver.rb, line 213 def resolve(**args) raise GraphQL::RequiredImplementationMissingError, "#{self.class.name}#resolve should execute the field's logic" end