Module: GraphQL::Schema::Member::HasFields Private

Includes:
EmptyObjects
Included in:
Interface::DefinitionMethods, GraphQL::Schema::Mutation, Object, Subscription
Defined in:
lib/graphql/schema/member/has_fields.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Shared code for Objects, Interfaces, Mutations, Subscriptions

Defined Under Namespace

Modules: InterfaceMethods, ObjectMethods

Constant Summary collapse

RUBY_KEYWORDS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

A list of Ruby keywords.

[:class, :module, :def, :undef, :begin, :rescue, :ensure, :end, :if, :unless, :then, :elsif, :else, :case, :when, :while, :until, :for, :break, :next, :redo, :retry, :in, :do, :return, :yield, :super, :self, :nil, :true, :false, :and, :or, :not, :alias, :defined?, :BEGIN, :END, :__LINE__, :__FILE__]
GRAPHQL_RUBY_KEYWORDS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

A list of GraphQL-Ruby keywords.

[:context, :object, :raw_value]
CONFLICT_FIELD_NAMES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

A list of field names that we should advise users to pick a different resolve method name.

Set.new(GRAPHQL_RUBY_KEYWORDS + RUBY_KEYWORDS + Object.instance_methods)

Constants included from EmptyObjects

EmptyObjects::EMPTY_ARRAY, EmptyObjects::EMPTY_HASH

Instance Method Summary collapse

Instance Method Details

#add_field(field_defn, method_conflict_warning: field_defn.method_conflict_warning?) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Register this field with the class, overriding a previous one if needed.

Parameters:



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/graphql/schema/member/has_fields.rb', line 108

def add_field(field_defn, method_conflict_warning: field_defn.method_conflict_warning?)
  # Check that `field_defn.original_name` equals `resolver_method` and `method_sym` --
  # that shows that no override value was given manually.
  if method_conflict_warning &&
      CONFLICT_FIELD_NAMES.include?(field_defn.resolver_method) &&
      field_defn.original_name == field_defn.resolver_method &&
      field_defn.original_name == field_defn.method_sym &&
      field_defn.hash_key == NOT_CONFIGURED &&
      field_defn.dig_keys.nil?
    warn(conflict_field_name_warning(field_defn))
  end
  prev_defn = own_fields[field_defn.name]

  case prev_defn
  when nil
    own_fields[field_defn.name] = field_defn
  when Array
    prev_defn << field_defn
  when GraphQL::Schema::Field
    own_fields[field_defn.name] = [prev_defn, field_defn]
  else
    raise "Invariant: unexpected previous field definition for #{field_defn.name.inspect}: #{prev_defn.inspect}"
  end

  nil
end

#all_field_definitionsObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



171
172
173
174
175
176
177
178
179
180
181
# File 'lib/graphql/schema/member/has_fields.rb', line 171

def all_field_definitions
  all_fields = {}
  ancestors.reverse_each do |ancestor|
    if ancestor.respond_to?(:own_fields)
      all_fields.merge!(ancestor.own_fields)
    end
  end
  all_fields = all_fields.values
  all_fields.flatten!
  all_fields
end

#field(name_positional = nil, type_positional = nil, desc_positional = nil, **kwargs, &definition_block) {|field| ... } ⇒ GraphQL::Schema::Field

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Add a field to this object or interface with the given definition

Parameters:

  • name_positional (Symbol) (defaults to: nil)

    The underscore-cased version of this field name (will be camelized for the GraphQL API); name: keyword is also accepted

  • type_positional (Class, GraphQL::BaseType, Array) (defaults to: nil)

    The return type of this field; type: keyword is also accepted

  • desc_positional (String) (defaults to: nil)

    Field description; description: keyword is also accepted

  • kwargs (Hash)

    Keywords for defining the field. Any not documented here will be passed to your base field class where they must be handled.

  • definition_block (Proc)

    an additional block for configuring the field. Receive the field as a block param, or, if no block params are defined, then the block is instance_eval‘d on the new Field.

Options Hash (**kwargs):

  • :name (Symbol)

    The underscore-cased version of this field name (will be camelized for the GraphQL API); positional argument also accepted

  • :type (Class, GraphQL::BaseType, Array)

    The return type of this field; positional argument is also accepted

  • :null (Boolean) — default: defaults to `true`

    true if this field may return null, false if it is never null

  • :description (String)

    Field description; positional argument also accepted

  • :comment (String)

    Field comment

  • :deprecation_reason (String)

    If present, the field is marked “deprecated” with this message

  • :method (Symbol)

    The method to call on the underlying object to resolve this field (defaults to name)

  • :hash_key (String, Symbol)

    The hash key to lookup on the underlying object (if its a Hash) to resolve this field (defaults to name or name.to_s)

  • :dig (Array<String, Symbol>)

    The nested hash keys to lookup on the underlying hash to resolve this field using dig

  • :resolver_method (Symbol)

    The method on the type to call to resolve this field (defaults to name)

  • :connection (Boolean)

    true if this field should get automagic connection behavior; default is to infer by *Connection in the return type name

  • :connection_extension (Class)

    The extension to add, to implement connections. If nil, no extension is added.

  • :max_page_size (Integer, nil)

    For connections, the maximum number of items to return from this field, or nil to allow unlimited results.

  • :default_page_size (Integer, nil)

    For connections, the default number of items to return from this field, or nil to return unlimited results.

  • :introspection (Boolean)

    If true, this field will be marked as #introspection? and the name may begin with __

  • :arguments ({String=>GraphQL::Schema::Argument, Hash})

    Arguments for this field (may be added in the block, also)

  • :camelize (Boolean)

    If true, the field name will be camelized when building the schema

  • :complexity (Numeric)

    When provided, set the complexity for this field

  • :scope (Boolean)

    If true, the return type’s .scope_items method will be called on the return value

  • :subscription_scope (Symbol, String)

    A key in context which will be used to scope subscription payloads

  • :extensions (Array<Class, Hash<Class => Object>>)

    Named extensions to apply to this field (see also #extension)

  • :directives (Hash{Class => Hash})

    Directives to apply to this field

  • :trace (Boolean)

    If true, a Tracing tracer will measure this scalar field

  • :broadcastable (Boolean)

    Whether or not this field can be distributed in subscription broadcasts

  • :ast_node (Language::Nodes::FieldDefinition, nil)

    If this schema was parsed from definition, this AST node defined the field

  • :method_conflict_warning (Boolean)

    If false, skip the warning if this field’s method conflicts with a built-in method

  • :validates (Array<Hash>)

    Configurations for validating this field

  • :fallback_value (Object)

    A fallback value if the method is not defined

  • :mutation (Class<GraphQL::Schema::Mutation>)
  • :resolver (Class<GraphQL::Schema::Resolver>)
  • :subscription (Class<GraphQL::Schema::Subscription>)
  • :dynamic_introspection (Boolean) — default: Private, used by GraphQL-Ruby
  • :relay_node_field (Boolean) — default: Private, used by GraphQL-Ruby
  • :relay_nodes_field (Boolean) — default: Private, used by GraphQL-Ruby
  • :extras (Array<:ast_node, :parent, :lookahead, :owner, :execution_errors, :graphql_name, :argument_details, Symbol>)

    Extra arguments to be injected into the resolver for this field

Yield Parameters:

Yield Returns:

  • (void)

Returns:



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/graphql/schema/member/has_fields.rb', line 53

def field(name_positional = nil, type_positional = nil, desc_positional = nil, **kwargs, &definition_block)
  resolver = kwargs.delete(:resolver)
  mutation = kwargs.delete(:mutation)
  subscription = kwargs.delete(:subscription)
  if (resolver_class = resolver || mutation || subscription)
    # Add a reference to that parent class
    kwargs[:resolver_class] = resolver_class
  end

  kwargs[:name] ||= name_positional
  if !type_positional.nil?
    if desc_positional
      if kwargs[:description]
        raise ArgumentError, "Provide description as a positional argument or `description:` keyword, but not both (#{desc_positional.inspect}, #{kwargs[:description].inspect})"
      end

      kwargs[:description] = desc_positional
      kwargs[:type] = type_positional
    elsif (resolver || mutation) && type_positional.is_a?(String)
      # The return type should be copied from the resolver, and the second positional argument is the description
      kwargs[:description] = type_positional
    else
      kwargs[:type] = type_positional
    end

    if type_positional.is_a?(Class) && type_positional < GraphQL::Schema::Mutation
      raise ArgumentError, "Use `field #{name_positional.inspect}, mutation: Mutation, ...` to provide a mutation to this field instead"
    end
  end

  kwargs[:owner] = self
  field_defn = field_class.new(**kwargs, &definition_block)
  add_field(field_defn)
  field_defn
end

#field_class(new_field_class = nil) ⇒ Class

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns The class to initialize when adding fields to this kind of schema member.

Returns:

  • (Class)

    The class to initialize when adding fields to this kind of schema member



136
137
138
139
140
141
142
143
144
# File 'lib/graphql/schema/member/has_fields.rb', line 136

def field_class(new_field_class = nil)
  if new_field_class
    @field_class = new_field_class
  elsif defined?(@field_class) && @field_class
    @field_class
  else
    find_inherited_value(:field_class, GraphQL::Schema::Field)
  end
end

#global_id_field(field_name, **kwargs) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



146
147
148
149
150
151
152
# File 'lib/graphql/schema/member/has_fields.rb', line 146

def global_id_field(field_name, **kwargs)
  type = self
  field field_name, "ID", **kwargs, null: false
  define_method(field_name) do
    context.schema.id_from_object(object, type, context)
  end
end

#has_no_fields(new_has_no_fields) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Parameters:

  • new_has_no_fields (Boolean)

    Call with true to make this Object type ignore the requirement to have any defined fields.



156
157
158
159
# File 'lib/graphql/schema/member/has_fields.rb', line 156

def has_no_fields(new_has_no_fields)
  @has_no_fields = new_has_no_fields
  nil
end

#has_no_fields?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns true if has_no_fields(true) was configued.

Returns:

  • (Boolean)

    true if has_no_fields(true) was configued



162
163
164
# File 'lib/graphql/schema/member/has_fields.rb', line 162

def has_no_fields?
  @has_no_fields
end

#own_fieldsHash<String => GraphQL::Schema::Field, Array<GraphQL::Schema::Field>>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns Fields defined on this class specifically, not parent classes.

Returns:



167
168
169
# File 'lib/graphql/schema/member/has_fields.rb', line 167

def own_fields
  @own_fields ||= {}
end