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
  # Mulitply 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: Resolve

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Define::InstanceDefinable

#definition_proc=, included, #metadata

Constructor Details

#initialize ⇒ Field

Returns a new instance of Field.



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

def initialize
  @complexity = 1
  @arguments = {}
  @resolve_proc = build_default_resolver
end

Instance Attribute Details

#arguments ⇒ Hash<String => GraphQL::Argument>

Returns Map String argument names to their Argument implementations.

Returns:



139
140
141
142
# File 'lib/graphql/field.rb', line 139

def arguments
  ensure_defined
  @arguments
end

#complexity ⇒ Numeric, 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



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

def complexity
  ensure_defined
  @complexity
end

#name ⇒ String

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

Returns:



131
132
133
134
# File 'lib/graphql/field.rb', line 131

def name
  ensure_defined
  @name
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



128
129
130
# File 'lib/graphql/field.rb', line 128

def resolve_proc
  @resolve_proc
end

Instance Method Details

#hash_key=(new_hash_key) ⇒ Object

Parameters:

  • new_hash_key (Symbol) —

    A key to access with #[key] to resolve this field. Overrides the existing resolve proc.



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

def hash_key=(new_hash_key)
  ensure_defined
  @hash_key = new_hash_key
  self.resolve = nil # reset resolve proc
end

#property=(new_property) ⇒ Object

Parameters:

  • new_property (Symbol) —

    A method to call to resolve this field. Overrides the existing resolve proc.



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

def property=(new_property)
  ensure_defined
  @property = new_property
  self.resolve = nil # reset resolve proc
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)


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

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

#resolve=(resolve_proc) ⇒ Object



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

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

#to_s ⇒ Object



218
219
220
# File 'lib/graphql/field.rb', line 218

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

#type ⇒ Object

Get the return type for this field.



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

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

#type=(new_return_type) ⇒ Object



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

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