Repository URL to install this package:
|
Version:
1.8.2 ▾
|
# frozen_string_literal: true
module GraphQL
# A reusable container for field logic, including arguments, resolve, return type, and documentation.
#
# Class-level values defined with the DSL will be inherited,
# so {GraphQL::Function}s can extend one another.
#
# It's OK to override the instance methods here in order to customize behavior of instances.
#
# @example A reusable GraphQL::Function attached as a field
# class FindRecord < GraphQL::Function
# attr_reader :type
#
# def initialize(model:, type:)
# @model = model
# @type = type
# end
#
# argument :id, GraphQL::ID_TYPE
#
# def call(obj, args, ctx)
# @model.find(args.id)
# end
# end
#
# QueryType = GraphQL::ObjectType.define do
# name "Query"
# field :post, function: FindRecord.new(model: Post, type: PostType)
# field :comment, function: FindRecord.new(model: Comment, type: CommentType)
# end
#
# @see {GraphQL::Schema::Resolver} for a replacement for `GraphQL::Function`
class Function
# @return [Hash<String => GraphQL::Argument>] Arguments, keyed by name
def arguments
self.class.arguments
end
# @return [GraphQL::BaseType] Return type
def type
self.class.type
end
# @return [Object] This function's resolver
def call(obj, args, ctx)
raise NotImplementedError
end
# @return [String, nil]
def description
self.class.description
end
# @return [String, nil]
def deprecation_reason
self.class.deprecation_reason
end
# @return [Integer, Proc]
def complexity
self.class.complexity || 1
end
class << self
# Define an argument for this function & its subclasses
# @see {GraphQL::Field} same arguments as the `argument` definition helper
# @return [void]
def argument(*args, **kwargs, &block)
argument = GraphQL::Argument.from_dsl(*args, **kwargs, &block)
own_arguments[argument.name] = argument
nil
end
# @return [Hash<String => GraphQL::Argument>] Arguments for this function class, including inherited arguments
def arguments
if parent_function?
own_arguments.merge(superclass.arguments)
else
own_arguments.dup
end
end
# Provides shorthand access to GraphQL's built-in types
def types
GraphQL::Define::TypeDefiner.instance
end
# Get or set the return type for this function class & descendants
# @return [GraphQL::BaseType]
def type(premade_type = nil, &block)
if block_given?
@type = GraphQL::ObjectType.define(&block)
elsif premade_type
@type = premade_type
elsif parent_function?
@type || superclass.type
else
@type
end
end
def build_field(function)
GraphQL::Field.define(
arguments: function.arguments,
complexity: function.complexity,
type: function.type,
resolve: function,
description: function.description,
function: function,
deprecation_reason: function.deprecation_reason,
)
end
# Class-level reader/writer which is inherited
# @api private
def self.inherited_value(name)
self.class_eval <<-RUBY
def #{name}(new_value = nil)
if new_value
@#{name} = new_value
elsif parent_function?
@#{name} || superclass.#{name}
else
@#{name}
end
end
RUBY
end
# @!method description(new_value = nil)
# Get or set this class's description
inherited_value(:description)
# @!method deprecation_reason(new_value = nil)
# Get or set this class's deprecation_reason
inherited_value(:deprecation_reason)
# @!method complexity(new_value = nil)
# Get or set this class's complexity
inherited_value(:complexity)
private
# Does this function inherit from another function?
def parent_function?
superclass <= GraphQL::Function
end
# Arguments defined on this class (not superclasses)
def own_arguments
@own_arguments ||= {}
end
end
end
end