@@ -5,40 +5,78 @@ module GraphQL
5
5
#
6
6
# They're usually created with the `field` helper. If you create it by hand, make sure {#name} is a String.
7
7
#
8
- # @example creating a field
8
+ # A field must have a return type, but if you want to defer the return type calculation until later,
9
+ # you can pass a proc for the return type. That proc will be called when the schema is defined.
10
+ #
11
+ # @example Lazy type resolution
12
+ # # If the field's type isn't defined yet, you can pass a proc
13
+ # field :city, -> { TypeForModelName.find("City") }
14
+ #
15
+ # For complex field definition, you can pass a block to the `field` helper, eg `field :name do ... end`.
16
+ # This block is equivalent to calling `GraphQL::Field.define { ... }`.
17
+ #
18
+ # @example Defining a field with a block
19
+ # field :city, CityType do
20
+ # # field definition continues inside the block
21
+ # end
22
+ #
23
+ # ## Resolve
24
+ #
25
+ # Fields have `resolve` functions to determine their values at query-time.
26
+ # The default implementation is to call a method on the object based on the field name.
27
+ #
28
+ # @example Create a field which calls a method with the same name.
9
29
# GraphQL::ObjectType.define do
10
30
# field :name, types.String, "The name of this thing "
11
31
# end
12
32
#
13
- # @example handling a circular reference
14
- # # If the field's type isn't defined yet, you have two options:
33
+ # You can specify a custom proc with the `resolve` helper.
34
+ #
35
+ # There are some shortcuts for common `resolve` implementations:
36
+ # - Provide `property:` to call a method with a different name than the field name
37
+ # - Provide `hash_key:` to resolve the field by doing a key lookup, eg `obj[:my_hash_key]`
15
38
#
39
+ # @example Create a field that calls a different method on the object
16
40
# GraphQL::ObjectType.define do
17
- # # If you pass a Proc, it will be evaluated at schema build-time
18
- # field :city, -> { CityType }
19
- # # If you pass a String, it will be looked up in the global namespace at schema build-time
20
- # field :country, "CountryType"
41
+ # # use the `property` keyword:
42
+ # field :firstName, types.String, property: :first_name
21
43
# end
22
44
#
23
- # @example creating a field that accesses a different property on the object
45
+ # @example Create a field looks up with `[hash_key]`
24
46
# GraphQL::ObjectType.define do
25
- # # use the `property` option :
26
- # field :firstName, types.String, property : :first_name
47
+ # # use the `hash_key` keyword :
48
+ # field :firstName, types.String, hash_key : :first_name
27
49
# end
28
50
#
29
- # @example defining a field, then attaching it to a type
30
- # name_field = GraphQL::Field.define do
31
- # name("Name")
32
- # type(!types.String)
33
- # description("The name of this thing")
34
- # resolve -> (object, arguments, context) { object.name }
51
+ # ## Arguments
52
+ #
53
+ # Fields can take inputs; they're called arguments. You can define them with the `argument` helper.
54
+ #
55
+ # @example Create a field with an argument
56
+ # field :students, types[StudentType] do
57
+ # argument :grade, types.Int
58
+ # resolve -> (obj, args, ctx) {
59
+ # Student.where(grade: args[:grade])
60
+ # }
35
61
# end
36
62
#
37
- # NamedType = GraphQL::ObjectType.define do
38
- # # use the `field` option:
39
- # field :name, field: name_field
63
+ # They can have default values which will be provided to `resolve` if the query doesn't include a value.
64
+ #
65
+ # @example Argument with a default value
66
+ # field :events, types[EventType] do
67
+ # # by default, don't include past events
68
+ # argument :includePast, types.Boolean, default_value: false
69
+ # resolve -> (obj, args, ctx) {
70
+ # args[:includePast] # => false if no value was provided in the query
71
+ # # ...
72
+ # }
40
73
# end
41
74
#
75
+ # ## Complexity
76
+ #
77
+ # Fields can have _complexity_ values which describe the computation cost of resolving the field.
78
+ # You can provide the complexity as a constant with `complexity:` or as a proc, with the `complexity` helper.
79
+ #
42
80
# @example Custom complexity values
43
81
# # Complexity can be a number or a proc.
44
82
#
@@ -57,12 +95,26 @@ module GraphQL
57
95
# complexity -> (ctx, args, child_complexity) { child_complexity * args[:limit] }
58
96
# end
59
97
#
98
+ # @example Creating a field, then assigning it to a type
99
+ # name_field = GraphQL::Field.define do
100
+ # name("Name")
101
+ # type(!types.String)
102
+ # description("The name of this thing")
103
+ # resolve -> (object, arguments, context) { object.name }
104
+ # end
105
+ #
106
+ # NamedType = GraphQL::ObjectType.define do
107
+ # # The second argument may be a GraphQL::Field
108
+ # field :name, name_field
109
+ # end
110
+ #
60
111
class Field
61
112
include GraphQL ::Define ::InstanceDefinable
62
113
accepts_definitions :name , :description , :resolve , :type , :property , :deprecation_reason , :complexity , :hash_key , argument : GraphQL ::Define ::AssignArgument
63
114
64
115
lazy_defined_attr_accessor :deprecation_reason , :description , :property , :hash_key
65
116
117
+ # @return [<#call(obj, args,ctx)>] A proc-like object which can be called to return the field's value
66
118
attr_reader :resolve_proc
67
119
68
120
# @return [String] The name of this field on its {GraphQL::ObjectType} (or {GraphQL::InterfaceType})
0 commit comments