graphql_rails 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cfcbe2a73989218dd084672e7402c553db62d23825096ba28f8a8af615c8ec63
4
- data.tar.gz: dee48916b9b0ee8c4205c4c69b62dd7a2608fd66c58e720792349f53be9508e9
3
+ metadata.gz: cd207ff4c895c9024b121bb5de205b289d8d2e54266022cfcc8e167fae2af097
4
+ data.tar.gz: c95bc639ce9adecf31ebc3c11e70a8214de31663c41be1aa539e70b1a04350f7
5
5
  SHA512:
6
- metadata.gz: cd658ca5e90d844b191ef11bbc87f5bd2f1e69cdcc07d4ce56726e3b9c23bc5c7c5056745c69d1fe95a322d67dcea131c9b8c6c14a566ee199b7d835cec508bc
7
- data.tar.gz: c6637e6f95b4b48e671f5d3a0303bb33a8327cbfec4b93da41f64e7331728578f02ca33240a37b4bc8b7c371965acbd353d9263f36f7bbc9d94062d4b3dc62fc
6
+ metadata.gz: 272d3e7b1ddad299aa58fc2fff01a2e9e336771495e04e5e279ead269ac3ac7a003621a1d7e81fcdb822b82ad61d07138b38443fe1b128403058b607a9175dad
7
+ data.tar.gz: 5b237e8afd7d7c9c098e3d0ab62e388ed09469bfb1b86874fa1c7c6ea05d9f7199bb430853f9dce81999567bfd197856a5c4514267a3d1fe5adfd6cf914fce5a
@@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  * Added/Changed/Deprecated/Removed/Fixed/Security: YOUR CHANGE HERE
11
11
 
12
+ ## 0.7.0 (2019-05-15)
13
+
14
+ * Added: input type now accepts `enum` param which allows create enum fields
15
+ * Added: routes now accepts `suffix: true` flag which generates GraphQL field with appended action name to the end of resource name
16
+
12
17
  ## 0.6.0 (2019-04-29)
13
18
 
14
19
  * Breaking change: controller params are always underscored [@povilasjurcys](https://github.com/povilasjurcys).
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- graphql_rails (0.6.0)
4
+ graphql_rails (0.7.0)
5
5
  activesupport (>= 4)
6
6
  graphql (~> 1)
7
7
 
@@ -1,5 +1,9 @@
1
1
  # GraphqlRails
2
2
 
3
+ [![Build Status](https://travis-ci.org/samesystem/graphql_rails.svg?branch=master)](https://travis-ci.org/samesystem/graphql_rails)
4
+ [![codecov](https://codecov.io/gh/samesystem/graphql_rails/branch/master/graph/badge.svg)](https://codecov.io/gh/samesystem/graphql_rails)
5
+ [![Documentation](https://readthedocs.org/projects/ansicolortags/badge/?version=latest)](https://samesystem.github.io/graphql_rails)
6
+
3
7
  Rails style structure for GraphQL API.
4
8
 
5
9
  ## Installation
@@ -167,6 +171,9 @@ RSpec.describe MyGraphqlController, type: :graphql_controller do
167
171
  end
168
172
  ```
169
173
 
174
+ ## Detailed documentation
175
+
176
+ Check https://samesystem.github.io/graphql_rails for more details
170
177
 
171
178
  ## Development
172
179
 
@@ -176,7 +183,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
176
183
 
177
184
  ## Contributing
178
185
 
179
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/graphql_rails. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
186
+ Bug reports and pull requests are welcome on GitHub at https://github.com/samesystem/graphql_rails. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
180
187
 
181
188
  ## License
182
189
 
@@ -184,4 +191,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
184
191
 
185
192
  ## Code of Conduct
186
193
 
187
- Everyone interacting in the GraphqlRails project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/graphql_rails/blob/master/CODE_OF_CONDUCT.md).
194
+ Everyone interacting in the GraphqlRails project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/samesystem/graphql_rails/blob/master/CODE_OF_CONDUCT.md).
@@ -15,15 +15,15 @@ class User # works with any class including ActiveRecord
15
15
  end
16
16
  ```
17
17
 
18
- ## _graphql_
18
+ ## graphql
19
19
 
20
20
  This method must be called inside your model body. `grapqhl` is used for making your model convertible to graphql type.
21
21
 
22
- ### _attribute_
22
+ ## attribute
23
23
 
24
24
  Most commonly you will use `attribute` to make your model methods and attributes visible via graphql endpoint.
25
25
 
26
- #### _type_
26
+ ## attribute type
27
27
 
28
28
  Some types can be determined by attribute name, so you can skip this attribute:
29
29
 
@@ -54,7 +54,7 @@ class User
54
54
  end
55
55
  ```
56
56
 
57
- #### _property_
57
+ ### attribute property
58
58
 
59
59
  By default graphql attribute names are expected to be same as model methods/attributes, but if you want to use different name on grapqhl side, you can use `propery` option:
60
60
 
@@ -72,7 +72,7 @@ class User
72
72
  end
73
73
  ```
74
74
 
75
- #### _description_
75
+ ### attribute description
76
76
 
77
77
  You can also describe each attribute and make graphql documentation even more readable. To do so, add `description` option:
78
78
 
@@ -86,7 +86,7 @@ class User
86
86
  end
87
87
  ```
88
88
 
89
- ### _name_
89
+ ## name
90
90
 
91
91
  By default grapqhl type name will be same as model name, but you can change it via `name` method
92
92
 
@@ -100,7 +100,7 @@ class User
100
100
  end
101
101
  ```
102
102
 
103
- ### _description_
103
+ ## description
104
104
 
105
105
  To improve grapqhl documentation, you can description for your graphql type:
106
106
 
@@ -114,10 +114,87 @@ class User
114
114
  end
115
115
  ```
116
116
 
117
- ### *graphql_type*
117
+ ## graphql_type
118
118
 
119
119
  Sometimes it's handy to get raw graphql type. To do so you can call:
120
120
 
121
121
  ```ruby
122
122
  YourModel.graphql.grapqhl_type
123
123
  ```
124
+
125
+ ## input
126
+
127
+ You can define input types:
128
+
129
+ ```ruby
130
+ class User
131
+ include GraphqlRails::Model
132
+
133
+ graphql.input do |c|
134
+ c.attribute :name
135
+ end
136
+ end
137
+ ```
138
+
139
+ Also you can have multiple input types:
140
+
141
+ ```ruby
142
+ class User
143
+ include GraphqlRails::Model
144
+
145
+ graphql.input(:create) do |c|
146
+ c.attribute :name
147
+ end
148
+
149
+ graphql.input(:update) do |c|
150
+ c.attribute :id
151
+ c.attribute :name
152
+ end
153
+ end
154
+ ```
155
+
156
+ ### input attribute
157
+
158
+ Most commonly you will use `attribute` to define what kind of values your endpoint accepts
159
+
160
+ #### input type
161
+
162
+ You can specify your input attribute type. If type is not provided then type is set to `:string`.
163
+
164
+ ```ruby
165
+ class User
166
+ include GraphqlRails::Model
167
+
168
+ graphql.input do |c|
169
+ c.attribute :friends_count, type: :integer!
170
+ end
171
+ end
172
+ ```
173
+
174
+ #### input enum type
175
+
176
+ You can specify your input attribute as enum:
177
+
178
+ ```ruby
179
+ class User
180
+ include GraphqlRails::Model
181
+
182
+ graphql.input do |c|
183
+ c.attribute :favorite_fruit, enum: %i[apple orange]
184
+ end
185
+ end
186
+ ```
187
+
188
+ #### input attribute description
189
+
190
+ To improve graphql endpoint documentation, you can add description for each input attribute:
191
+
192
+ ```ruby
193
+ class User
194
+ include GraphqlRails::Model
195
+
196
+ graphql.input do |c|
197
+ c.attribute :name, description: "User's first name"
198
+ end
199
+ end
200
+ ```
@@ -30,7 +30,7 @@ MyGraphqlSchema = GraphqlRails::Router.draw do
30
30
  end
31
31
  ```
32
32
 
33
- ## _resources_
33
+ ## resources
34
34
 
35
35
  `resources` method generates routes to `index`, `show`, `create`, `update` and `destroy` controller actions.
36
36
 
@@ -59,6 +59,20 @@ MyGraphqlSchema = GraphqlRails::Router.draw do
59
59
  end
60
60
  ```
61
61
 
62
+ #### Appending name to the end of resource name
63
+
64
+ Sometimes, especially when working with member queries, it sounds better when action name is added to the end of resource name instead of start. To do so, you can add `suffix: true` to route:
65
+
66
+ ```ruby
67
+ MyGraphqlSchema = GraphqlRails::Router.draw do
68
+ resouces :users do
69
+ query :details, on: :member, suffix: true
70
+ end
71
+ end
72
+ ```
73
+
74
+ This will generate `userDetails` field on GraphQL side.
75
+
62
76
  ## _query_ and _mutation_
63
77
 
64
78
  in case you want to have non-CRUD controller with custom actions you can define your own `query`/`mutation` actions like this:
@@ -4,7 +4,7 @@ require 'graphql_rails/version'
4
4
  require 'graphql_rails/model'
5
5
  require 'graphql_rails/router'
6
6
  require 'graphql_rails/controller'
7
- require 'graphql_rails/attribute'
7
+ require 'graphql_rails/attributes'
8
8
 
9
9
  # wonders starts here
10
10
  module GraphqlRails
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlRails
4
+ # attributes namespace
5
+ module Attributes
6
+ require_relative './attributes/attributable'
7
+ require_relative './attributes/attribute'
8
+ require_relative './attributes/input_attribute'
9
+
10
+ require_relative './attributes/type_parser'
11
+ require_relative './attributes/attribute_name_parser'
12
+ end
13
+ end
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'graphql_rails/attribute/type_parser'
4
- require 'graphql_rails/attribute/attribute_name_parser'
3
+ require 'graphql_rails/attributes/type_parser'
4
+ require 'graphql_rails/attributes/attribute_name_parser'
5
5
 
6
6
  module GraphqlRails
7
- class Attribute
7
+ module Attributes
8
8
  # contains methods which are shared between various attribute-like classes
9
9
  # expects `initial_name` and `initial_type` to be defined
10
10
  module Attributable
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql'
4
+ require 'graphql_rails/attributes/attributable'
5
+
6
+ module GraphqlRails
7
+ module Attributes
8
+ # contains info about single graphql attribute
9
+ class Attribute
10
+ include Attributable
11
+
12
+ attr_reader :property, :description
13
+
14
+ def initialize(name, type = nil, description: nil, property: name)
15
+ @initial_type = type
16
+ @initial_name = name
17
+ @description = description
18
+ @property = property.to_s
19
+ end
20
+
21
+ def field_args
22
+ [field_name, graphql_field_type, { property: property.to_sym, description: description }]
23
+ end
24
+
25
+ protected
26
+
27
+ attr_reader :initial_type, :initial_name
28
+ end
29
+ end
30
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphqlRails
4
- class Attribute
4
+ module Attributes
5
5
  # Parses attribute name and can generates graphql scalar type,
6
6
  # grapqhl name and etc. based on that
7
7
  class AttributeNameParser
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphqlRails
4
- module Model
4
+ module Attributes
5
5
  # contains info about single graphql input attribute
6
6
  class InputAttribute
7
- include GraphqlRails::Attribute::Attributable
7
+ include Attributable
8
8
 
9
9
  attr_reader :description
10
10
 
@@ -3,7 +3,7 @@
3
3
  require 'graphql'
4
4
 
5
5
  module GraphqlRails
6
- class Attribute
6
+ module Attributes
7
7
  # converts string value in to GraphQL type
8
8
  class TypeParser
9
9
  class UnknownTypeError < ArgumentError; end
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_support/core_ext/string/filters'
4
- require 'graphql_rails/attribute/type_parser'
5
- require 'graphql_rails/attribute'
6
- require 'graphql_rails/model/input_attribute'
4
+ require 'graphql_rails/attributes'
7
5
 
8
6
  module GraphqlRails
9
7
  class Controller
@@ -86,12 +84,12 @@ module GraphqlRails
86
84
  end
87
85
 
88
86
  def type_parser
89
- GraphqlRails::Attribute::TypeParser.new(custom_return_type)
87
+ Attributes::TypeParser.new(custom_return_type)
90
88
  end
91
89
 
92
90
  def permit_attribute(name, type = nil)
93
91
  field_name = name.to_s.remove(/!\Z/)
94
- attributes[field_name] = Model::InputAttribute.new(name.to_s, type, options: action_options)
92
+ attributes[field_name] = Attributes::InputAttribute.new(name.to_s, type, options: action_options)
95
93
  end
96
94
  end
97
95
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_support/core_ext/string/inflections'
4
- require 'graphql_rails/attribute'
5
4
  require 'graphql_rails/controller/action_configuration'
6
5
  require 'graphql_rails/controller/action_hook'
7
6
 
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphqlRails
4
+ require 'graphql'
5
+
4
6
  # base class which is returned in case something bad happens. Contains all error rendering tructure
5
7
  class ExecutionError < GraphQL::ExecutionError
6
8
  def to_h
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql'
4
+ require 'graphql_rails/attributes/attributable'
5
+
6
+ module GraphqlRails
7
+ module Model
8
+ # contains info about single graphql attribute
9
+ class BuildEnumType
10
+ def self.call(*args)
11
+ new(*args).call
12
+ end
13
+
14
+ def initialize(name, allowed_values:, description: nil)
15
+ @name = name
16
+ @allowed_values = allowed_values
17
+ @description = description
18
+ end
19
+
20
+ def call
21
+ allowed_values = self.allowed_values
22
+ enum_name = name.to_s.camelize
23
+ enum_description = description
24
+
25
+ Class.new(GraphQL::Schema::Enum) do
26
+ allowed_values.each do |allowed_value|
27
+ graphql_name(enum_name)
28
+ description(enum_description) if enum_description
29
+ value(allowed_value.to_s.underscore.upcase, value: allowed_value)
30
+ end
31
+ end
32
+ end
33
+
34
+ protected
35
+
36
+ attr_reader :name, :allowed_values, :description
37
+ end
38
+ end
39
+ end
@@ -3,7 +3,11 @@
3
3
  module GraphqlRails
4
4
  module Model
5
5
  # stores information about model specific config, like attributes and types
6
- class GraphqlInputTypeBuilder
6
+ class BuildGraphqlInputType
7
+ def self.call(*args)
8
+ new(*args).call
9
+ end
10
+
7
11
  def initialize(name:, description: nil, attributes:)
8
12
  @name = name
9
13
  @attributes = attributes
@@ -3,7 +3,11 @@
3
3
  module GraphqlRails
4
4
  module Model
5
5
  # stores information about model specific config, like attributes and types
6
- class GraphqlTypeBuilder
6
+ class BuildGraphqlType
7
+ def self.call(*args)
8
+ new(*args).call
9
+ end
10
+
7
11
  def initialize(name:, description: nil, attributes:)
8
12
  @name = name
9
13
  @attributes = attributes
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'graphql_rails/attribute'
4
- require 'graphql_rails/model/graphql_type_builder'
3
+ require 'graphql_rails/attributes'
4
+ require 'graphql_rails/model/build_graphql_type'
5
+ require 'graphql_rails/model/build_enum_type'
5
6
  require 'graphql_rails/model/input'
6
7
  require 'graphql_rails/model/configurable'
7
8
  require 'graphql_rails/model/configuration/count_items'
@@ -18,7 +19,7 @@ module GraphqlRails
18
19
 
19
20
  def attribute(attribute_name, type: nil, **attribute_options)
20
21
  attributes[attribute_name.to_s] = \
21
- Attribute.new(
22
+ Attributes::Attribute.new(
22
23
  attribute_name,
23
24
  type,
24
25
  attribute_options
@@ -35,14 +36,14 @@ module GraphqlRails
35
36
  end
36
37
 
37
38
  @input.fetch(name) do
38
- raise("GraphQL input with name #{input_name.inspect} is not defined for #{model_class}")
39
+ raise("GraphQL input with name #{input_name.inspect} is not defined for #{model_class.name}")
39
40
  end
40
41
  end
41
42
 
42
43
  def graphql_type
43
- @graphql_type ||= GraphqlTypeBuilder.new(
44
+ @graphql_type ||= BuildGraphqlType.call(
44
45
  name: name, description: description, attributes: attributes
45
- ).call
46
+ )
46
47
  end
47
48
 
48
49
  def connection_type
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'graphql_rails/model/graphql_input_type_builder'
3
+ require 'graphql_rails/model/build_graphql_input_type'
4
4
  require 'graphql_rails/model/configurable'
5
5
 
6
6
  module GraphqlRails
@@ -15,16 +15,16 @@ module GraphqlRails
15
15
  end
16
16
 
17
17
  def graphql_input_type
18
- @graphql_input_type ||= GraphqlInputTypeBuilder.new(
18
+ @graphql_input_type ||= BuildGraphqlInputType.call(
19
19
  name: name, description: description, attributes: attributes
20
- ).call
20
+ )
21
21
  end
22
22
 
23
- def attribute(attribute_name, type: nil, **attribute_options)
23
+ def attribute(attribute_name, type: nil, enum: nil, **attribute_options)
24
24
  attributes[attribute_name.to_s] = \
25
- InputAttribute.new(
25
+ GraphqlRails::Attributes::InputAttribute.new(
26
26
  attribute_name,
27
- type,
27
+ attribute_type(attribute_name, type: type, enum: enum, **attribute_options),
28
28
  attribute_options
29
29
  )
30
30
  end
@@ -39,6 +39,16 @@ module GraphqlRails
39
39
  "#{model_class.name.split('::').last}#{suffix}Input"
40
40
  end
41
41
  end
42
+
43
+ def attribute_type(attribute_name, type:, enum:, description: nil, **_other)
44
+ return type unless enum
45
+
46
+ BuildEnumType.call(
47
+ "#{name}_#{attribute_name}_enum",
48
+ allowed_values: enum,
49
+ description: description
50
+ )
51
+ end
42
52
  end
43
53
  end
44
54
  end
@@ -62,11 +62,18 @@ module GraphqlRails
62
62
  build_route(QueryRoute, *args)
63
63
  end
64
64
 
65
- def build_route(builder, action, prefix: action, on: :member, **custom_options)
65
+ # rubocop:disable Metrics/ParameterLists
66
+ def build_route(builder, action, prefix: action, suffix: false, on: :member, **custom_options)
67
+ if suffix == true
68
+ suffix_name = action
69
+ prefix = ''
70
+ end
71
+
66
72
  action_options = options.merge(custom_options).merge(on: on)
67
- action_name = [prefix, resource_name(on)].reject(&:empty?).join('_')
73
+ action_name = [prefix, resource_name(on), suffix_name].map(&:to_s).reject(&:empty?).join('_')
68
74
  builder.new(action_name, to: "#{name}##{action}", **action_options)
69
75
  end
76
+ # rubocop:enable Metrics/ParameterLists
70
77
 
71
78
  def initial_action_names(only, except, available)
72
79
  alowed_routes = Array(only || available) & available
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphqlRails
4
- VERSION = '0.6.0'
4
+ VERSION = '0.7.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Povilas Jurčys
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-04-29 00:00:00.000000000 Z
11
+ date: 2019-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -126,7 +126,6 @@ files:
126
126
  - Gemfile
127
127
  - Gemfile.lock
128
128
  - LICENSE.txt
129
- - README.md
130
129
  - Rakefile
131
130
  - bin/console
132
131
  - bin/setup
@@ -142,10 +141,12 @@ files:
142
141
  - docs/testing/testing.md
143
142
  - graphql_rails.gemspec
144
143
  - lib/graphql_rails.rb
145
- - lib/graphql_rails/attribute.rb
146
- - lib/graphql_rails/attribute/attributable.rb
147
- - lib/graphql_rails/attribute/attribute_name_parser.rb
148
- - lib/graphql_rails/attribute/type_parser.rb
144
+ - lib/graphql_rails/attributes.rb
145
+ - lib/graphql_rails/attributes/attributable.rb
146
+ - lib/graphql_rails/attributes/attribute.rb
147
+ - lib/graphql_rails/attributes/attribute_name_parser.rb
148
+ - lib/graphql_rails/attributes/input_attribute.rb
149
+ - lib/graphql_rails/attributes/type_parser.rb
149
150
  - lib/graphql_rails/controller.rb
150
151
  - lib/graphql_rails/controller/action.rb
151
152
  - lib/graphql_rails/controller/action_configuration.rb
@@ -159,13 +160,13 @@ files:
159
160
  - lib/graphql_rails/errors/execution_error.rb
160
161
  - lib/graphql_rails/errors/validation_error.rb
161
162
  - lib/graphql_rails/model.rb
163
+ - lib/graphql_rails/model/build_enum_type.rb
164
+ - lib/graphql_rails/model/build_graphql_input_type.rb
165
+ - lib/graphql_rails/model/build_graphql_type.rb
162
166
  - lib/graphql_rails/model/configurable.rb
163
167
  - lib/graphql_rails/model/configuration.rb
164
168
  - lib/graphql_rails/model/configuration/count_items.rb
165
- - lib/graphql_rails/model/graphql_input_type_builder.rb
166
- - lib/graphql_rails/model/graphql_type_builder.rb
167
169
  - lib/graphql_rails/model/input.rb
168
- - lib/graphql_rails/model/input_attribute.rb
169
170
  - lib/graphql_rails/router.rb
170
171
  - lib/graphql_rails/router/mutation_route.rb
171
172
  - lib/graphql_rails/router/plain_cursor_encoder.rb
data/README.md DELETED
@@ -1,194 +0,0 @@
1
- # GraphqlRails
2
-
3
- [![Build Status](https://travis-ci.org/samesystem/graphql_rails.svg?branch=master)](https://travis-ci.org/samesystem/graphql_rails)
4
- [![codecov](https://codecov.io/gh/samesystem/graphql_rails/branch/master/graph/badge.svg)](https://codecov.io/gh/samesystem/graphql_rails)
5
- [![Documentation](https://readthedocs.org/projects/ansicolortags/badge/?version=latest)](https://samesystem.github.io/graphql_rails)
6
-
7
- Rails style structure for GraphQL API.
8
-
9
- ## Installation
10
-
11
- Add this line to your application's Gemfile:
12
-
13
- ```ruby
14
- gem 'graphql_rails'
15
- ```
16
-
17
- And then execute:
18
-
19
- $ bundle
20
-
21
- Or install it yourself as:
22
-
23
- $ gem install graphql_rails
24
-
25
- ## Usage
26
-
27
- ### Define GraphQL schema as RoR routes
28
-
29
- ```ruby
30
- MyGraphqlSchema = GraphqlRails::Router.draw do
31
- # will create createUser, updateUser, deleteUser mutations and user, users queries.
32
- # expects that UsersController class exist
33
- resources :users
34
-
35
- # if you want custom queries or mutation
36
- query 'searchLogs', to: 'logs#search' # redirects request to LogsController
37
- mutation 'changeUserPassword', to: 'users#change_password'
38
- end
39
- ```
40
-
41
- ### Define your Graphql model
42
-
43
- ```ruby
44
- class User # works with any class including ActiveRecord
45
- include GraphqlRails::Model
46
-
47
- graphql do |c|
48
- # most common attributes, like :id, :name, :title has default type, so you don't have to specify it (but you can!)
49
- c.attribute :id
50
-
51
- c.attribute :email, type: :string
52
- c.attribute :surname, type: :string
53
- end
54
- end
55
- ```
56
-
57
- ### Define controller
58
-
59
- ```ruby
60
- class UsersController < GraphqlRails::Controller
61
- # graphql requires to describe which attributes controller action accepts and which returns
62
- action(:change_user_password)
63
- .permit(:password!, :id!) # Bang (!) indicates that attribute is required
64
-
65
- def change_user_password
66
- user = User.find(params[:id])
67
- user.update!(password: params[:password])
68
-
69
- # returned value needs to have all methods defined in model `graphql do` part
70
- user # or SomeDecorator.new(user)
71
- end
72
-
73
- action(:search).permit(search_fields!: SearchFieldsInput) # you can specify your own input fields
74
- def search
75
- end
76
- end
77
- ```
78
-
79
- ## Routes
80
-
81
- ```ruby
82
- MyGraphqlSchema = GraphqlRails::Router.draw do
83
- # generates `friend`, `createFriend`, `updateFriend`, `destroyFriend`, `friends` routes
84
- resources :friends
85
- resources :shops, only: [:show, :index] # generates `shop` and `shops` routes only
86
- resources :orders, except: :update # generates all routes except `updateOrder`
87
-
88
- resources :users do
89
- # generates `findUser` query
90
- query :find, on: :member
91
-
92
- # generates `searchUsers` query
93
- query :search, on: :collection
94
- end
95
-
96
- # you can use namespaced controllers too:
97
- scope module: 'admin' do
98
- # `updateTranslations` route will be handeled by `Admin::TranslationsController`
99
- mutation :updateTranslations, to: 'translations#update'
100
-
101
- # all :groups routes will be handeled by `Admin::GroupsController`
102
- resources :groups
103
- end
104
- end
105
- ```
106
-
107
- ## Testing your GraphqlRails::Controller in RSpec
108
-
109
- ### Setup
110
-
111
- Add those lines in your `spec/spec_helper.rb` file
112
-
113
- ```ruby
114
- # spec/spec_helper.rb
115
- require 'graphql_rails/rspec_controller_helpers'
116
-
117
- RSpec.configure do |config|
118
- config.include(GraphqlRails::RSpecControllerHelpers, type: :graphql_controller)
119
- # ... your other configuration ...
120
- end
121
- ```
122
-
123
- ### Helper methods
124
-
125
- There are 3 helper methods:
126
-
127
- * `mutation(:your_controller_action_name, params: {}, context: {})`. `params` and `context` are optional
128
- * `query(:your_controller_action_name, params: {}, context: {})`. `params` and `context` are optional
129
- * `response`. Response is set only after you call `mutation` or `query`
130
-
131
- ### Test examples
132
-
133
- ```ruby
134
- class MyGraphqlController
135
- def index
136
- "Called from index: #{params[:message]}"
137
- end
138
-
139
- action(:create_user).permit(:full_name, :email)
140
- def create_user
141
- User.create!(params)
142
- end
143
- end
144
-
145
- RSpec.describe MyGraphqlController, type: :graphql_controller do
146
- describe '#index' do
147
- it 'is successful' do
148
- query(:index)
149
- expect(response).to be_successful
150
- end
151
-
152
- it 'returns correct message' do
153
- query(:index, params: { message: 'Hello world!' })
154
- expect(response.result).to eq "Called from index: Hello world!"
155
- end
156
- end
157
-
158
- describe '#create_user' do
159
- context 'when bad email is given' do
160
- it 'fails' do
161
- mutation(:create_user, params { email: 'bad' })
162
- expect(response).to be_failure
163
- end
164
-
165
- it 'contains errors' do
166
- mutation(:create_user, params { email: 'bad' })
167
- expect(response.errors).not_to be_empty
168
- end
169
- end
170
- end
171
- end
172
- ```
173
-
174
- ## Detailed documentation
175
-
176
- Check https://samesystem.github.io/graphql_rails for more details
177
-
178
- ## Development
179
-
180
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
181
-
182
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
183
-
184
- ## Contributing
185
-
186
- Bug reports and pull requests are welcome on GitHub at https://github.com/samesystem/graphql_rails. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
187
-
188
- ## License
189
-
190
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
191
-
192
- ## Code of Conduct
193
-
194
- Everyone interacting in the GraphqlRails project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/samesystem/graphql_rails/blob/master/CODE_OF_CONDUCT.md).
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'graphql'
4
- require 'graphql_rails/attribute/attributable'
5
-
6
- module GraphqlRails
7
- # contains info about single graphql attribute
8
- class Attribute
9
- include Attributable
10
-
11
- attr_reader :property, :description
12
-
13
- def initialize(name, type = nil, description: nil, property: name)
14
- @initial_type = type
15
- @initial_name = name
16
- @description = description
17
- @property = property.to_s
18
- end
19
-
20
- def field_args
21
- [field_name, graphql_field_type, { property: property.to_sym, description: description }]
22
- end
23
-
24
- protected
25
-
26
- attr_reader :initial_type, :initial_name
27
- end
28
- end