Class: GraphQL::Field

Inherits:
Object
  • Object
show all
Includes:
Define::InstanceDefinable
Defined in:
lib/graphql/field.rb,
lib/graphql/field/resolve.rb

Overview

Fields belong to ObjectTypes and InterfaceTypes.

They're usually created with the field helper. If you create it by hand, make sure #name is a String.

A field must have a return type, but if you want to defer the return type calculation until later, you can pass a proc for the return type. That proc will be called when the schema is defined.

For complex field definition, you can pass a block to the field helper, eg field :name do ... end. This block is equivalent to calling GraphQL::Field.define { ... }.

Resolve

Fields have resolve functions to determine their values at query-time. The default implementation is to call a method on the object based on the field name.

You can specify a custom proc with the resolve helper.

There are some shortcuts for common resolve implementations:

  • Provide property: to call a method with a different name than the field name
  • Provide hash_key: to resolve the field by doing a key lookup, eg obj[:my_hash_key]

Arguments

Fields can take inputs; they're called arguments. You can define them with the argument helper.

They can have default values which will be provided to resolve if the query doesn't include a value.

Only certain types maybe used for inputs:

  • Scalars
  • Enums
  • Input Objects
  • Lists of those types

Input types may also be non-null -- in that case, the query will fail if the input is not present.

Complexity

Fields can have complexity values which describe the computation cost of resolving the field. You can provide the complexity as a constant with complexity: or as a proc, with the complexity helper.

Examples:

Lazy type resolution

# If the field's type isn't defined yet, you can pass a proc
field :city, -> { TypeForModelName.find("City") }

Defining a field with a block

field :city, CityType do
  # field definition continues inside the block
end

Create a field which calls a method with the same name.

GraphQL::ObjectType.define do
  field :name, types.String, "The name of this thing "
end

Create a field that calls a different method on the object

GraphQL::ObjectType.define do
  # use the `property` keyword:
  field :firstName, types.String, property: :first_name
end

Create a field looks up with [hash_key]

GraphQL::ObjectType.define do
  # use the `hash_key` keyword:
  field :firstName, types.String, hash_key: :first_name
end

Create a field with an argument

field :students, types[StudentType] do
  argument :grade, types.Int
  resolve ->(obj, args, ctx) {
    Student.where(grade: args[:grade])
  }
end

Argument with a default value

field :events, types[EventType] do
  # by default, don't include past events
  argument :includePast, types.Boolean, default_value: false
  resolve ->(obj, args, ctx) {
    args[:includePast] # => false if no value was provided in the query
    # ...
  }
end

Custom complexity values

# Complexity can be a number or a proc.

# Complexity can be defined with a keyword:
field :expensive_calculation, !types.Int, complexity: 10

# Or inside the block:
field :expensive_calculation_2, !types.Int do
  complexity ->(ctx, args, child_complexity) { ctx[:current_user].staff? ? 0 : 10 }
end

Calculating the complexity of a list field

field :items, types[ItemType] do
  argument :limit, !types.Int
  # Multiply the child complexity by the possible items on the list
  complexity ->(ctx, args, child_complexity) { child_complexity * args[:limit] }
end

Creating a field, then assigning it to a type

name_field = GraphQL::Field.define do
  name("Name")
  type(!types.String)
  description("The name of this thing")
  resolve ->(object, arguments, context) { object.name }
end

NamedType = GraphQL::ObjectType.define do
  # The second argument may be a GraphQL::Field
  field :name, name_field
end

Defined Under Namespace

Modules: DefaultLazyResolve, Resolve

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Define::InstanceDefinable

#define, #metadata, #redefine

Constructor Details

#initializeField

Returns a new instance of Field



216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/graphql/field.rb', line 216

def initialize
  @complexity = 1
  @arguments = {}
  @resolve_proc = build_default_resolver
  @lazy_resolve_proc = DefaultLazyResolve
  @relay_node_field = false
  @connection = false
  @connection_max_page_size = nil
  @edge_class = nil
  @trace = nil
  @introspection = false
end

Instance Attribute Details

#argumentsHash<String => GraphQL::Argument>

Returns Map String argument names to their Argument implementations

Returns:



169
170
171
# File 'lib/graphql/field.rb', line 169

def arguments
  @arguments
end

#arguments_classObject

Returns the value of attribute arguments_class



186
187
188
# File 'lib/graphql/field.rb', line 186

def arguments_class
  @arguments_class
end

#ast_nodeObject

Returns the value of attribute ast_node



197
198
199
# File 'lib/graphql/field.rb', line 197

def ast_node
  @ast_node
end

#complexityNumeric, Proc

Returns The complexity for this field (default: 1), as a constant or a proc like ->(query_ctx, args, child_complexity) { } # Numeric

Returns:

  • (Numeric, Proc)

    The complexity for this field (default: 1), as a constant or a proc like ->(query_ctx, args, child_complexity) { } # Numeric



175
176
177
# File 'lib/graphql/field.rb', line 175

def complexity
  @complexity
end

#connection=(value) ⇒ Object (writeonly)

Sets the attribute connection

Parameters:

  • value

    the value to set the attribute connection to.



188
189
190
# File 'lib/graphql/field.rb', line 188

def connection=(value)
  @connection = value
end

#connection_max_page_sizenil, Integer

Returns:

  • (nil, Integer)


214
215
216
# File 'lib/graphql/field.rb', line 214

def connection_max_page_size
  @connection_max_page_size
end

#deprecation_reasonString?

Returns The client-facing reason why this field is deprecated (if present, the field is deprecated)

Returns:

  • (String, nil)

    The client-facing reason why this field is deprecated (if present, the field is deprecated)



166
167
168
# File 'lib/graphql/field.rb', line 166

def deprecation_reason
  @deprecation_reason
end

#descriptionString?

Returns The client-facing description of this field

Returns:

  • (String, nil)

    The client-facing description of this field



163
164
165
# File 'lib/graphql/field.rb', line 163

def description
  @description
end

#edge_classnil, 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:

  • (nil, Class)


206
207
208
# File 'lib/graphql/field.rb', line 206

def edge_class
  @edge_class
end

#functionObject, GraphQL::Function

Returns The function used to derive this field

Returns:



184
185
186
# File 'lib/graphql/field.rb', line 184

def function
  @function
end

#hash_keyObject?

Returns The key to access with obj.[] to resolve this field (overrides #name if present)

Returns:

  • (Object, nil)

    The key to access with obj.[] to resolve this field (overrides #name if present)



181
182
183
# File 'lib/graphql/field.rb', line 181

def hash_key
  @hash_key
end

#introspection=(value) ⇒ Object (writeonly)

Sets the attribute introspection

Parameters:

  • value

    the value to set the attribute introspection to.



189
190
191
# File 'lib/graphql/field.rb', line 189

def introspection=(value)
  @introspection = value
end

#lazy_resolve_proc<#call(obj, args, ctx)> (readonly)

Returns A proc-like object which can be called trigger a lazy resolution

Returns:

  • (<#call(obj, args, ctx)>)

    A proc-like object which can be called trigger a lazy resolution



156
157
158
# File 'lib/graphql/field.rb', line 156

def lazy_resolve_proc
  @lazy_resolve_proc
end

#mutationGraphQL::Relay::Mutation?

Returns The mutation this field was derived from, if it was derived from a mutation

Returns:



172
173
174
# File 'lib/graphql/field.rb', line 172

def mutation
  @mutation
end

#nameString Also known as: graphql_name

Returns The name of this field on its ObjectType (or InterfaceType)

Returns:



159
160
161
# File 'lib/graphql/field.rb', line 159

def name
  @name
end

#propertySymbol?

Returns The method to call on obj to return this field (overrides #name if present)

Returns:

  • (Symbol, nil)

    The method to call on obj to return this field (overrides #name if present)



178
179
180
# File 'lib/graphql/field.rb', line 178

def property
  @property
end

#relay_node_fieldBoolean

Returns True if this is the Relay find-by-id field

Returns:

  • (Boolean)

    True if this is the Relay find-by-id field



147
148
149
# File 'lib/graphql/field.rb', line 147

def relay_node_field
  @relay_node_field
end

#relay_nodes_fieldBoolean

Returns True if this is the Relay find-by-ids field

Returns:

  • (Boolean)

    True if this is the Relay find-by-ids field



150
151
152
# File 'lib/graphql/field.rb', line 150

def relay_nodes_field
  @relay_nodes_field
end

#resolve_proc<#call(obj, args, ctx)> (readonly)

Returns A proc-like object which can be called to return the field's value

Returns:

  • (<#call(obj, args, ctx)>)

    A proc-like object which can be called to return the field's value



153
154
155
# File 'lib/graphql/field.rb', line 153

def resolve_proc
  @resolve_proc
end

#subscription_scopenil, String

Returns Prefix for subscription names from this field

Returns:

  • (nil, String)

    Prefix for subscription names from this field



192
193
194
# File 'lib/graphql/field.rb', line 192

def subscription_scope
  @subscription_scope
end

#traceBoolean

Returns True if this field should be traced. By default, fields are only traced if they are not a ScalarType or EnumType.

Returns:

  • (Boolean)

    True if this field should be traced. By default, fields are only traced if they are not a ScalarType or EnumType.



195
196
197
# File 'lib/graphql/field.rb', line 195

def trace
  @trace
end

Instance Method Details

#connection?Boolean

Returns:

  • (Boolean)


200
201
202
# File 'lib/graphql/field.rb', line 200

def connection?
  @connection
end

#edges?Boolean

Returns:

  • (Boolean)


209
210
211
# File 'lib/graphql/field.rb', line 209

def edges?
  !!@edge_class
end

#initialize_copy(other) ⇒ Object



229
230
231
232
233
# File 'lib/graphql/field.rb', line 229

def initialize_copy(other)
  ensure_defined
  super
  @arguments = other.arguments.dup
end

#introspection?Boolean

Returns Is this field a predefined introspection field?

Returns:

  • (Boolean)

    Is this field a predefined introspection field?



236
237
238
# File 'lib/graphql/field.rb', line 236

def introspection?
  @introspection
end

#lazy_resolve(obj, args, ctx) ⇒ Object

If #resolve returned an object which should be handled lazily, this method will be called later to force the object to return its value.

Parameters:

Returns:

  • (Object)

    The result of calling the registered method on obj



301
302
303
# File 'lib/graphql/field.rb', line 301

def lazy_resolve(obj, args, ctx)
  @lazy_resolve_proc.call(obj, args, ctx)
end

#lazy_resolve=(new_lazy_resolve_proc) ⇒ Object

Assign a new resolve proc to this field. Used for #lazy_resolve



306
307
308
# File 'lib/graphql/field.rb', line 306

def lazy_resolve=(new_lazy_resolve_proc)
  @lazy_resolve_proc = new_lazy_resolve_proc
end

#prepare_lazy(obj, args, ctx) ⇒ GraphQL::Execution::Lazy

Prepare a lazy value for this field. It may be then-ed and resolved later.

Returns:



312
313
314
315
316
# File 'lib/graphql/field.rb', line 312

def prepare_lazy(obj, args, ctx)
  GraphQL::Execution::Lazy.new {
    lazy_resolve(obj, args, ctx)
  }
end

#resolve(object, arguments, context) ⇒ Object

Get a value for this field

Examples:

resolving a field value

field.resolve(obj, args, ctx)

Parameters:

  • object (Object)

    The object this field belongs to

  • arguments (Hash)

    Arguments declared in the query

  • context (GraphQL::Query::Context)


247
248
249
# File 'lib/graphql/field.rb', line 247

def resolve(object, arguments, context)
  resolve_proc.call(object, arguments, context)
end

#resolve=(new_resolve_proc) ⇒ Object

Provide a new callable for this field's resolve function. If nil, a new resolve proc will be build based on its #name, #property or #hash_key.

Parameters:

  • new_resolve_proc (<#call(obj, args, ctx)>, nil)


254
255
256
# File 'lib/graphql/field.rb', line 254

def resolve=(new_resolve_proc)
  @resolve_proc = new_resolve_proc || build_default_resolver
end

#to_sObject



291
292
293
# File 'lib/graphql/field.rb', line 291

def to_s
  "<Field name:#{name || "not-named"} desc:#{description} resolve:#{resolve_proc}>"
end

#typeObject

Get the return type for this field.



264
265
266
# File 'lib/graphql/field.rb', line 264

def type
  @clean_type ||= GraphQL::BaseType.resolve_related_type(@dirty_type)
end

#type=(new_return_type) ⇒ Object



258
259
260
261
# File 'lib/graphql/field.rb', line 258

def type=(new_return_type)
  @clean_type = nil
  @dirty_type = new_return_type
end