graphql 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graph_ql/argument.rb +38 -4
  3. data/lib/graph_ql/boolean_type.rb +3 -5
  4. data/lib/graph_ql/definition_helpers.rb +1 -0
  5. data/lib/graph_ql/definition_helpers/defined_by_config.rb +20 -0
  6. data/lib/graph_ql/enum_type.rb +52 -16
  7. data/lib/graph_ql/field.rb +79 -14
  8. data/lib/graph_ql/float_type.rb +3 -3
  9. data/lib/graph_ql/id_type.rb +3 -5
  10. data/lib/graph_ql/input_object_type.rb +41 -4
  11. data/lib/graph_ql/int_type.rb +3 -5
  12. data/lib/graph_ql/interface_type.rb +36 -8
  13. data/lib/graph_ql/introspection/arguments_field.rb +4 -4
  14. data/lib/graph_ql/introspection/directive_type.rb +9 -11
  15. data/lib/graph_ql/introspection/enum_value_type.rb +9 -12
  16. data/lib/graph_ql/introspection/enum_values_field.rb +6 -8
  17. data/lib/graph_ql/introspection/field_type.rb +11 -15
  18. data/lib/graph_ql/introspection/fields_field.rb +5 -7
  19. data/lib/graph_ql/introspection/input_fields_field.rb +5 -5
  20. data/lib/graph_ql/introspection/input_value_type.rb +7 -9
  21. data/lib/graph_ql/introspection/interfaces_field.rb +4 -4
  22. data/lib/graph_ql/introspection/of_type_field.rb +5 -5
  23. data/lib/graph_ql/introspection/possible_types_field.rb +4 -4
  24. data/lib/graph_ql/introspection/schema_field.rb +6 -8
  25. data/lib/graph_ql/introspection/schema_type.rb +19 -25
  26. data/lib/graph_ql/introspection/type_by_name_field.rb +7 -1
  27. data/lib/graph_ql/introspection/type_kind_enum.rb +4 -4
  28. data/lib/graph_ql/introspection/type_type.rb +18 -18
  29. data/lib/graph_ql/introspection/typename_field.rb +6 -10
  30. data/lib/graph_ql/object_type.rb +87 -12
  31. data/lib/graph_ql/scalar_type.rb +22 -0
  32. data/lib/graph_ql/schema.rb +1 -1
  33. data/lib/graph_ql/string_type.rb +3 -5
  34. data/lib/graph_ql/union_type.rb +24 -3
  35. data/lib/graph_ql/version.rb +1 -1
  36. data/lib/graphql.rb +1 -1
  37. data/readme.md +66 -64
  38. data/spec/graph_ql/field_spec.rb +3 -3
  39. data/spec/support/dairy_app.rb +119 -133
  40. data/spec/support/dairy_data.rb +1 -1
  41. data/spec/support/star_wars_schema.rb +50 -57
  42. metadata +3 -2
@@ -2,6 +2,28 @@ module GraphQL
2
2
  # The parent type for scalars, eg {GraphQL::STRING_TYPE}, {GraphQL::INT_TYPE}
3
3
  #
4
4
  class ScalarType < GraphQL::ObjectType
5
+ class DefinitionConfig < GraphQL::ObjectType::DefinitionConfig
6
+ attr_definable :coerce
7
+
8
+ def type_class
9
+ GraphQL::ScalarType
10
+ end
11
+
12
+ def to_instance
13
+ scalar_type = super
14
+ scalar_type.coerce = coerce
15
+ scalar_type
16
+ end
17
+ end
18
+
19
+ def coerce(value)
20
+ @coerce.call(value)
21
+ end
22
+
23
+ def coerce=(proc)
24
+ @coerce = proc
25
+ end
26
+
5
27
  def kind
6
28
  GraphQL::TypeKinds::SCALAR
7
29
  end
@@ -7,7 +7,7 @@ class GraphQL::Schema
7
7
 
8
8
  # @param query [GraphQL::ObjectType] the query root for the schema
9
9
  # @param mutation [GraphQL::ObjectType, nil] the mutation root for the schema
10
- def initialize(query:, mutation:)
10
+ def initialize(query:, mutation: nil)
11
11
  @query = query
12
12
  @mutation = mutation
13
13
  @directives = DIRECTIVES.reduce({}) { |m, d| m[d.name] = d; m }
@@ -1,6 +1,4 @@
1
- GraphQL::STRING_TYPE = GraphQL::ScalarType.new do |t|
2
- t.name "String"
3
- def t.coerce(value)
4
- value.to_s
5
- end
1
+ GraphQL::STRING_TYPE = GraphQL::ScalarType.define do
2
+ name "String"
3
+ coerce -> (value) { value.to_s }
6
4
  end
@@ -1,15 +1,36 @@
1
1
  # A collection of {ObjectType}s
2
2
  #
3
3
  # @example a union of types
4
- # PetUnion = GraphQL::UnionType.new("Pet", "House pets", [DogType, CatType])
4
+ #
5
+ # PetUnion = GraphQL::UnionType.define do
6
+ # name "Pet"
7
+ # description "Animals that live in your house"
8
+ # possible_types [DogType, CatType, FishType]
9
+ # end
5
10
  #
6
11
  class GraphQL::UnionType
7
12
  include GraphQL::DefinitionHelpers::NonNullWithBang
8
- attr_reader :name, :description, :possible_types
9
- def initialize(name, desc, types)
13
+ include GraphQL::DefinitionHelpers::DefinedByConfig
14
+ attr_accessor :name, :description, :possible_types
15
+
16
+ class DefinitionConfig
17
+ extend GraphQL::DefinitionHelpers::Definable
18
+ attr_definable :name, :description, :possible_types
19
+
20
+ def to_instance
21
+ object = GraphQL::UnionType.new
22
+ object.name = name
23
+ object.description = description
24
+ object.possible_types = possible_types
25
+ object
26
+ end
27
+ end
28
+
29
+ def initialize(name = nil, desc = nil, types = nil)
10
30
  @name = name
11
31
  @description = desc
12
32
  @possible_types = types
33
+ name && warn("Initializing with .new is deprecated, use .define instead! (see #{self})")
13
34
  end
14
35
 
15
36
  def kind
@@ -1,3 +1,3 @@
1
1
  module GraphQL
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -5,7 +5,7 @@ require "singleton"
5
5
  module GraphQL
6
6
  # Turn a query string into an AST
7
7
  # @param string [String] a GraphQL query string
8
- # @param as [Symbol] If you want to use this to parse some _piece_ of a document, pass the rule name (from {GraphQL::Parser::Parser})
8
+ # @param as [Symbol] If you want to use this to parse some _piece_ of a document, pass the rule name (from {GraphQL::Parser})
9
9
  # @return [GraphQL::Nodes::Document]
10
10
  def self.parse(string, as: nil)
11
11
  parser = as ? GraphQL::PARSER.send(as) : GraphQL::PARSER
data/readme.md CHANGED
@@ -9,72 +9,72 @@
9
9
  - [Introduction](https://github.com/rmosolgo/graphql-ruby/blob/master/guides/introduction.md)
10
10
  - [API Documentation](http://www.rubydoc.info/github/rmosolgo/graphql-ruby)
11
11
 
12
+ ## Installation
13
+
14
+ Install from RubyGems by adding it to your `Gemfile`, then bundling.
15
+
16
+ ```ruby
17
+ # Gemfile
18
+ gem 'graphql'
19
+ ```
20
+
21
+ ```
22
+ $ bundle install
23
+ ```
24
+
12
25
  ## Overview
13
26
 
14
- - __Install the gem__:
15
-
16
- ```ruby
17
- # Gemfile
18
- gem 'graphql'
19
- ```
20
-
21
- ```
22
- $ bundle install
23
- ```
24
-
25
- - __Declare types & build a schema__:
26
-
27
- ```ruby
28
- # Declare a type...
29
- PostType = GraphQL::ObjectType.new do |t, types, field|
30
- t.name "Post"
31
- t.description "A blog post"
32
- t.fields({
33
- id: field.build(type: !types.Int),
34
- title: field.build(type: !types.String),
35
- body: field.build(type: !types.String),
36
- comments: field.build(type: types[!CommentType])
37
- })
38
- end
27
+ #### Declare types & build a schema
39
28
 
40
- # ...and a query root
41
- QueryType = GraphQL::ObjectType.new do |t, types, field, arg|
42
- t.name "Query"
43
- t.description "The query root of this schema"
44
- t.fields({
45
- post: GraphQL::Field.new do |f|
46
- f.arguments(id: arg.build(type: !types.Int))
47
- f.resolve -> (object, args, context) {
48
- Post.find(args["id"])
49
- }
50
- end
51
- })
52
- end
29
+ ```ruby
30
+ # Declare a type...
31
+ PostType = GraphQL::ObjectType.define do
32
+ name "Post"
33
+ description "A blog post"
34
+
35
+ field :id, !types.ID
36
+ field :title, !types.String
37
+ field :body, !types.String
38
+ field :comments, types[!CommentType]
39
+ end
40
+
41
+ # ...and a query root
42
+ QueryType = GraphQL::ObjectType.define do
43
+ name "Query"
44
+ description "The query root of this schema"
53
45
 
54
- # Then create your schema
55
- Schema = GraphQL::Schema.new(query: QueryType, mutation: nil)
56
- ```
57
-
58
- See also:
59
- - the [test schema](https://github.com/rmosolgo/graphql-ruby/blob/master/spec/support/dummy_app.rb)
60
- - [`graphql-ruby-demo`](https://github.com/rmosolgo/graphql-ruby-demo) for an example schema on Rails
61
-
62
- - __Execute queries__:
63
-
64
- ```ruby
65
- query = GraphQL::Query.new(Schema, query_string)
66
- result_hash = query.result
67
- # {
68
- # "data" => {
69
- # "post" => {
70
- # "id" => 1,
71
- # "title" => "GraphQL is nice"
72
- # }
73
- # }
74
- # }
75
- ```
76
-
77
- See also:
46
+ field :post do
47
+ argument :id, !types.ID
48
+ resolve -> (obj, args, ctx) { Post.find(args["id"]) }
49
+ end
50
+ end
51
+
52
+ # Then create your schema
53
+ Schema = GraphQL::Schema.new(query: QueryType)
54
+ ```
55
+
56
+ See also:
57
+ - the [test schema](https://github.com/rmosolgo/graphql-ruby/blob/master/spec/support/dairy_app.rb)
58
+ - [`graphql-ruby-demo`](https://github.com/rmosolgo/graphql-ruby-demo) for an example schema on Rails
59
+
60
+ #### Execute queries
61
+
62
+ Execute GraphQL queries on a given schema, from a query string.
63
+
64
+ ```ruby
65
+ query = GraphQL::Query.new(Schema, query_string)
66
+ result_hash = query.result
67
+ # {
68
+ # "data" => {
69
+ # "post" => {
70
+ # "id" => 1,
71
+ # "title" => "GraphQL is nice"
72
+ # }
73
+ # }
74
+ # }
75
+ ```
76
+
77
+ See also:
78
78
  - [query_spec.rb](https://github.com/rmosolgo/graphql-ruby/blob/master/spec/graph_ql/query_spec.rb) for an example of query execution.
79
79
  - [`queries_controller.rb`](https://github.com/rmosolgo/graphql-ruby-demo/blob/master/app/controllers/queries_controller.rb) for a Rails example
80
80
  - Try it on [heroku](http://graphql-ruby-demo.herokuapp.com)
@@ -85,16 +85,17 @@
85
85
  - Directives:
86
86
  - `@skip` has precedence over `@include`
87
87
  - directives on fragments: http://facebook.github.io/graphql/#sec-Fragment-Directives
88
+ - Add static validation for empty string
89
+ - Only run named operation
88
90
  - Field merging
89
91
  - if you were to request a field, then request it in a fragment, it would get looked up twice
90
92
  - https://github.com/graphql/graphql-js/issues/19#issuecomment-118515077
91
93
  - Code clean-up
92
94
  - Unify unwrapping types (It's on `TypeKind` but it's still not right)
93
- - Better definition API
95
+ - Accept native Ruby types in definitions, then convert them to GraphQL types
94
96
  - Cook up some path other than "n+1s everywhere"
95
97
  - See Sangria's `project` approach ([in progress](https://github.com/rmosolgo/graphql-ruby/pull/15))
96
98
 
97
-
98
99
  ## Goals
99
100
 
100
101
  - Implement the GraphQL spec & support a Relay front end
@@ -118,3 +119,4 @@
118
119
  ## P.S.
119
120
 
120
121
  Thanks to @sgwilym for the great logo!
122
+ Definition API heavily inspired by @seanchas's [implementation of GraphQL](https://github.com/seanchas/graphql)
@@ -2,9 +2,9 @@ require 'spec_helper'
2
2
 
3
3
  describe GraphQL::Field do
4
4
  it 'accepts a proc as type' do
5
- field = GraphQL::Field.new { |f|
6
- f.type(-> { DairyProductUnion })
7
- }
5
+ field = GraphQL::Field.define do
6
+ type(-> { DairyProductUnion })
7
+ end
8
8
  assert_equal(DairyProductUnion, field.type)
9
9
  end
10
10
  end
@@ -1,164 +1,150 @@
1
1
  require_relative './dairy_data'
2
2
 
3
- EdibleInterface = GraphQL::InterfaceType.new do |i, type, field|
4
- i.name "Edible"
5
- i.description "Something you can eat, yum"
6
- i.fields({
7
- fatContent: field.build(
8
- type: !type.Float,
9
- property: :non_existent_field_that_should_never_be_called,
10
- desc: "Percentage which is fat"),
11
- })
3
+ EdibleInterface = GraphQL::InterfaceType.define do
4
+ name "Edible"
5
+ description "Something you can eat, yum"
6
+ field :fatContent, !types.Float, "Percentage which is fat", property: :bogus_property
12
7
  end
13
8
 
14
- AnimalProductInterface = GraphQL::InterfaceType.new do |i, type, field|
15
- i.name "AnimalProduct"
16
- i.description "Comes from an animal, no joke"
17
- i.fields({
18
- source: field.build(type: !type.String, desc: "Animal which produced this product"),
19
- })
9
+ AnimalProductInterface = GraphQL::InterfaceType.define do
10
+ name "AnimalProduct"
11
+ description "Comes from an animal, no joke"
12
+ field :source, !types.String, "Animal which produced this product"
20
13
  end
21
14
 
22
- DairyAnimalEnum = GraphQL::EnumType.new do |e|
23
- e.name "DairyAnimal"
24
- e.description "An animal which can yield milk"
25
- e.value("COW", "Animal with black and white spots", value: 1)
26
- e.value("GOAT", "Animal with horns")
27
- e.value("SHEEP", "Animal with wool")
28
- e.value("YAK", "Animal with long hair", deprecation_reason: "Out of fashion")
15
+ DairyAnimalEnum = GraphQL::EnumType.define do
16
+ name "DairyAnimal"
17
+ description "An animal which can yield milk"
18
+ value("COW", "Animal with black and white spots", value: 1)
19
+ value("GOAT", "Animal with horns")
20
+ value("SHEEP", "Animal with wool")
21
+ value("YAK", "Animal with long hair", deprecation_reason: "Out of fashion")
29
22
  end
30
23
 
31
- CheeseType = GraphQL::ObjectType.new do |t, type, field, arg|
32
- t.name "Cheese"
33
- t.description "Cultured dairy product"
34
- t.interfaces [EdibleInterface, AnimalProductInterface]
35
- t.fields = {
36
- id: field.build(type: !type.Int, desc: "Unique identifier"),
37
- flavor: field.build(type: !type.String, desc: "Kind of cheese"),
38
- source: field.build(type: !DairyAnimalEnum, desc: "Animal which produced the milk for this cheese"),
39
- similarCheeses: GraphQL::Field.new do |f|
40
- f.description "Cheeses like this one"
41
- f.type(t)
42
- f.arguments({source: arg.build(type: !type[!DairyAnimalEnum])})
43
- f.resolve -> (t, a, c) { CHEESES.values.find { |c| c.source == a["source"] } }
44
- end,
45
- fatContent: field.build(type: !type.Float, desc: "Percentage which is milkfat", deprecation_reason: "Diet fashion has changed"),
46
- }
47
- end
24
+ CheeseType = GraphQL::ObjectType.define do
25
+ name "Cheese"
26
+ description "Cultured dairy product"
27
+ interfaces [EdibleInterface, AnimalProductInterface]
48
28
 
49
- MilkType = GraphQL::ObjectType.new do |t, type, field, arg|
50
- t.name 'Milk'
51
- t.description "Dairy beverage"
52
- t.interfaces [EdibleInterface, AnimalProductInterface]
53
- t.fields = {
54
- id: field.build(type: !type.ID, desc: "Unique identifier"),
55
- source: field.build(type: DairyAnimalEnum, desc: "Animal which produced this milk"),
56
- fatContent: field.build(type: !type.Float, desc: "Percentage which is milkfat"),
57
- flavors: field.build(
58
- type: type[type.String],
59
- desc: "Chocolate, Strawberry, etc",
60
- args: {limit: arg.build({type: type.Int})}
61
- ),
62
- }
63
- end
29
+ # Can have (name, type, desc)
30
+ field :id, !types.Int, "Unique identifier"
31
+ field :flavor, !types.String, "Kind of Cheese"
64
32
 
65
- DairyProductUnion = GraphQL::UnionType.new(
66
- "DairyProduct",
67
- "Kinds of food made from milk",
68
- [MilkType, CheeseType]
69
- )
70
-
71
- DairyProductInputType = GraphQL::InputObjectType.new {|t, type, field, arg|
72
- t.name "DairyProductInput"
73
- t.description "Properties for finding a dairy product"
74
- t.input_fields({
75
- source: arg.build({type: DairyAnimalEnum}),
76
- fatContent: arg.build({type: type.Float}),
77
- })
78
- }
33
+ # Or can define by block:
34
+ field :source do
35
+ type(!DairyAnimalEnum)
36
+ description("Animal which produced the milk for this cheese")
37
+ end
79
38
 
39
+ field :similarCheeses do
40
+ type -> { CheeseType }
41
+ description("Cheeses like this one")
42
+ argument :source, !types[!DairyAnimalEnum]
43
+ resolve -> (t, a, c) { CHEESES.values.find { |c| c.source == a["source"] } }
44
+ end
80
45
 
81
- class FetchField
82
- attr_reader :type, :arguments, :deprecation_reason
83
- attr_accessor :name
84
- def initialize(type:, data:, id_type: !GraphQL::INT_TYPE)
85
- @type = type
86
- @data = data
87
- @arguments = {"id" => GraphQL::Argument.new(type: id_type, name: "id")}
88
- @deprecation_reason = nil
46
+ field fatContent: :fat_content do
47
+ type(!GraphQL::FLOAT_TYPE)
48
+ description("Percentage which is milkfat")
49
+ deprecation_reason("Diet fashion has changed")
89
50
  end
51
+ end
90
52
 
91
- def description
92
- "Find a #{@type.name} by id"
53
+ MilkType = GraphQL::ObjectType.define do
54
+ name 'Milk'
55
+ description "Dairy beverage"
56
+ interfaces [EdibleInterface, AnimalProductInterface]
57
+ field :id, !types.ID
58
+ field :source, DairyAnimalEnum, "Animal which produced this milk"
59
+ field :fatContent, !types.Float, "Percentage which is milkfat"
60
+ field :flavors, types[types.String], "Chocolate, Strawberry, etc" do
61
+ argument :limit, types.Int
93
62
  end
63
+ end
94
64
 
95
- def resolve(target, arguments, context)
96
- @data[arguments["id"].to_i]
65
+ DairyProductUnion = GraphQL::UnionType.define do
66
+ name "DairyProduct"
67
+ description "Kinds of food made from milk"
68
+ possible_types [MilkType, CheeseType]
69
+ end
70
+
71
+ DairyProductInputType = GraphQL::InputObjectType.define {
72
+ name "DairyProductInput"
73
+ description "Properties for finding a dairy product"
74
+ input_field :source, DairyAnimalEnum
75
+ input_field :fatContent, types.Float
76
+ }
77
+
78
+
79
+ class FetchField
80
+ def self.create(type:, data:, id_type: !GraphQL::INT_TYPE)
81
+ desc = "Find a #{type.name} by id"
82
+ return_type = type
83
+ GraphQL::Field.define do
84
+ type(return_type)
85
+ description(desc)
86
+ argument :id, id_type
87
+
88
+ resolve -> (t, a, c) { data[a["id"].to_i] }
89
+ end
97
90
  end
98
91
  end
99
92
 
100
- SourceField = GraphQL::Field.new do |f, type, field, arg|
101
- f.type GraphQL::ListType.new(of_type: CheeseType)
102
- f.description "Cheese from source"
103
- f.arguments(source: arg.build(type: !DairyAnimalEnum))
104
- f.resolve -> (target, arguments, context) {
93
+ SourceFieldDefn = Proc.new {
94
+ type GraphQL::ListType.new(of_type: CheeseType)
95
+ description "Cheese from source"
96
+ argument :source, !DairyAnimalEnum
97
+ resolve -> (target, arguments, context) {
105
98
  CHEESES.values.select{ |c| c.source == arguments["source"] }
106
99
  }
107
- end
100
+ }
108
101
 
109
- FavoriteField = GraphQL::Field.new do |f|
110
- f.description "My favorite food"
111
- f.type EdibleInterface
112
- f.resolve -> (t, a, c) { MILKS[1] }
113
- end
102
+ FavoriteFieldDefn = Proc.new {
103
+ description "My favorite food"
104
+ type EdibleInterface
105
+ resolve -> (t, a, c) { MILKS[1] }
106
+ }
114
107
 
108
+ QueryType = GraphQL::ObjectType.define do
109
+ name "Query"
110
+ description "Query root of the system"
111
+ field :cheese, field: FetchField.create(type: CheeseType, data: CHEESES)
112
+ field :milk, field: FetchField.create(type: MilkType, data: MILKS, id_type: !types.ID)
113
+ field :fromSource, &SourceFieldDefn
114
+ field :favoriteEdible, &FavoriteFieldDefn
115
+ field :searchDairy do
116
+ description "Find dairy products matching a description"
117
+ type !DairyProductUnion
118
+ argument :product, DairyProductInputType
119
+ resolve -> (t, a, c) {
120
+ products = CHEESES.values + MILKS.values
121
+ source = a["product"][:source] # String or sym is ok
122
+ if !source.nil?
123
+ products = products.select { |p| p.source == source }
124
+ end
125
+ products.first
126
+ }
127
+ end
115
128
 
116
- QueryType = GraphQL::ObjectType.new do |t, types, field, arg|
117
- t.name "Query"
118
- t.description "Query root of the system"
119
- t.fields({
120
- cheese: FetchField.new(type: CheeseType, data: CHEESES),
121
- milk: FetchField.new(type: MilkType, data: MILKS, id_type: !types.ID),
122
- fromSource: SourceField,
123
- favoriteEdible: FavoriteField,
124
- searchDairy: GraphQL::Field.new { |f|
125
- f.name "searchDairy"
126
- f.description "Find dairy products matching a description"
127
- f.type !DairyProductUnion
128
- f.arguments({product: arg.build({type: DairyProductInputType})})
129
- f.resolve -> (t, a, c) {
130
- products = CHEESES.values + MILKS.values
131
- source = a["product"][:source] # String or sym is ok
132
- if !source.nil?
133
- products = products.select { |p| p.source == source }
134
- end
135
- products.first
136
- }
137
- },
138
- error: GraphQL::Field.new { |f|
139
- f.description "Raise an error"
140
- f.type GraphQL::STRING_TYPE
141
- f.resolve -> (t, a, c) { raise("This error was raised on purpose") }
142
- },
143
- })
129
+ field :error do
130
+ description "Raise an error"
131
+ type GraphQL::STRING_TYPE
132
+ resolve -> (t, a, c) { raise("This error was raised on purpose") }
133
+ end
144
134
  end
145
135
 
146
136
  GLOBAL_VALUES = []
147
-
148
- MutationType = GraphQL::ObjectType.new do |t, type, field, arg|
149
- t.name "Mutation"
150
- t.description "The root for mutations in this schema"
151
- t.fields({
152
- pushValue: GraphQL::Field.new { |f|
153
- f.description("Push a value onto a global array :D")
154
- f.type(!type[!type.Int])
155
- f.arguments(value: arg.build(type: !type.Int))
156
- f.resolve -> (o, args, ctx) {
157
- GLOBAL_VALUES << args[:value]
158
- GLOBAL_VALUES
159
- }
137
+ MutationType = GraphQL::ObjectType.define do
138
+ name "Mutation"
139
+ description "The root for mutations in this schema"
140
+ field :pushValue, !types[!types.Int] do
141
+ description("Push a value onto a global array :D")
142
+ argument :value, !types.Int
143
+ resolve -> (o, args, ctx) {
144
+ GLOBAL_VALUES << args[:value]
145
+ GLOBAL_VALUES
160
146
  }
161
- })
147
+ end
162
148
  end
163
149
 
164
150
  DummySchema = GraphQL::Schema.new(query: QueryType, mutation: MutationType)