graphql_rails 2.1.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -1
  3. data/.ruby-version +1 -1
  4. data/CHANGELOG.md +14 -0
  5. data/Gemfile.lock +117 -116
  6. data/docs/README.md +23 -45
  7. data/docs/_sidebar.md +0 -1
  8. data/docs/components/controller.md +15 -1
  9. data/docs/components/decorator.md +1 -1
  10. data/docs/components/model.md +62 -0
  11. data/docs/components/routes.md +45 -8
  12. data/lib/graphql_rails/attributes/attribute.rb +8 -14
  13. data/lib/graphql_rails/attributes/attribute_configurable.rb +15 -0
  14. data/lib/graphql_rails/attributes/input_attribute.rb +17 -1
  15. data/lib/graphql_rails/attributes/type_parseable.rb +1 -7
  16. data/lib/graphql_rails/controller/build_controller_action_resolver.rb +2 -0
  17. data/lib/graphql_rails/controller/log_controller_action.rb +7 -2
  18. data/lib/graphql_rails/controller.rb +1 -1
  19. data/lib/graphql_rails/decorator/relation_decorator.rb +22 -18
  20. data/lib/graphql_rails/decorator.rb +12 -4
  21. data/lib/graphql_rails/errors/system_error.rb +11 -1
  22. data/lib/graphql_rails/errors/validation_error.rb +14 -1
  23. data/lib/graphql_rails/input_configurable.rb +1 -1
  24. data/lib/graphql_rails/model/find_or_build_graphql_type.rb +1 -5
  25. data/lib/graphql_rails/router/build_schema_action_type.rb +112 -0
  26. data/lib/graphql_rails/router/mutation_route.rb +4 -0
  27. data/lib/graphql_rails/router/query_route.rb +4 -0
  28. data/lib/graphql_rails/router/resource_routes_builder.rb +8 -0
  29. data/lib/graphql_rails/router/route.rb +3 -2
  30. data/lib/graphql_rails/router/schema_builder.rb +14 -18
  31. data/lib/graphql_rails/router/subscription_route.rb +22 -0
  32. data/lib/graphql_rails/router.rb +32 -10
  33. data/lib/graphql_rails/version.rb +1 -1
  34. metadata +5 -4
  35. data/docs/getting_started/quick_start.md +0 -62
@@ -5,12 +5,14 @@ module GraphqlRails
5
5
  # builds GraphQL::Schema based on previously defined grahiti data
6
6
  class SchemaBuilder
7
7
  require_relative './plain_cursor_encoder'
8
+ require_relative './build_schema_action_type'
8
9
 
9
- attr_reader :queries, :mutations, :raw_actions
10
+ attr_reader :queries, :mutations, :subscriptions, :raw_actions
10
11
 
11
- def initialize(queries:, mutations:, raw_actions:, group: nil)
12
+ def initialize(queries:, mutations:, subscriptions:, raw_actions:, group: nil)
12
13
  @queries = queries
13
14
  @mutations = mutations
15
+ @subscriptions = subscriptions
14
16
  @raw_actions = raw_actions
15
17
  @group = group
16
18
  end
@@ -18,6 +20,7 @@ module GraphqlRails
18
20
  def call
19
21
  query_type = build_group_type('Query', queries)
20
22
  mutation_type = build_group_type('Mutation', mutations)
23
+ subscription_type = build_group_type('Subscription', subscriptions)
21
24
  raw = raw_actions
22
25
 
23
26
  Class.new(GraphQL::Schema) do
@@ -30,6 +33,7 @@ module GraphqlRails
30
33
 
31
34
  query(query_type) if query_type
32
35
  mutation(mutation_type) if mutation_type
36
+ subscription(subscription_type) if subscription_type
33
37
  end
34
38
  end
35
39
 
@@ -39,24 +43,16 @@ module GraphqlRails
39
43
 
40
44
  def build_group_type(type_name, routes)
41
45
  group_name = group
42
- group_routes = routes.select { |route| route.show_in_group?(group_name) }
43
- return if group_routes.empty?
46
+ group_routes =
47
+ routes
48
+ .select { |route| route.show_in_group?(group_name) }
49
+ .reverse
50
+ .uniq(&:name)
51
+ .reverse
44
52
 
45
- build_type(type_name, group_routes)
46
- end
47
-
48
- def build_type(type_name, group_routes)
49
- Class.new(GraphQL::Schema::Object) do
50
- graphql_name(type_name)
53
+ return if group_routes.empty? && type_name != 'Query'
51
54
 
52
- group_routes.each do |route|
53
- field(*route.name, **route.field_options)
54
- end
55
-
56
- def self.inspect
57
- "#{GraphQL::Schema::Object}(#{graphql_name})"
58
- end
59
- end
55
+ BuildSchemaActionType.call(type_name: type_name, routes: group_routes)
60
56
  end
61
57
  end
62
58
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'route'
4
+
5
+ module GraphqlRails
6
+ class Router
7
+ # stores subscription type graphql action info
8
+ class SubscriptionRoute < Route
9
+ def query?
10
+ false
11
+ end
12
+
13
+ def mutation?
14
+ false
15
+ end
16
+
17
+ def subscription?
18
+ true
19
+ end
20
+ end
21
+ end
22
+ end
@@ -5,6 +5,7 @@ require 'active_support/core_ext/string/inflections'
5
5
  require 'graphql_rails/router/schema_builder'
6
6
  require 'graphql_rails/router/mutation_route'
7
7
  require 'graphql_rails/router/query_route'
8
+ require 'graphql_rails/router/subscription_route'
8
9
  require 'graphql_rails/router/resource_routes_builder'
9
10
 
10
11
  module GraphqlRails
@@ -20,13 +21,15 @@ module GraphqlRails
20
21
  end
21
22
  end
22
23
 
23
- attr_reader :routes, :namespace_name, :raw_graphql_actions
24
+ attr_reader :routes, :namespace_name, :raw_graphql_actions, :scope_names
24
25
 
25
- def initialize(module_name: '', group_names: [])
26
+ def initialize(module_name: '', group_names: [], scope_names: [])
27
+ @scope_names = scope_names
26
28
  @module_name = module_name
27
29
  @group_names = group_names
28
30
  @routes ||= Set.new
29
31
  @raw_graphql_actions ||= []
32
+ @graphql_schema = {}
30
33
  end
31
34
 
32
35
  def group(*group_names, &block)
@@ -35,13 +38,16 @@ module GraphqlRails
35
38
  routes.merge(scoped_router.routes)
36
39
  end
37
40
 
38
- def scope(**options, &block)
39
- full_module_name = [module_name, options[:module]].reject(&:empty?).join('/')
40
- scoped_router = router_with(module_name: full_module_name)
41
+ def scope(new_scope_name = nil, **options, &block)
42
+ scoped_router = router_with_scope_params(new_scope_name, **options)
41
43
  scoped_router.instance_eval(&block)
42
44
  routes.merge(scoped_router.routes)
43
45
  end
44
46
 
47
+ def namespace(namespace_name, &block)
48
+ scope(path: namespace_name, module: namespace_name, &block)
49
+ end
50
+
45
51
  def resources(name, **options, &block)
46
52
  builder_options = full_route_options(options)
47
53
  routes_builder = ResourceRoutesBuilder.new(name, **builder_options)
@@ -57,6 +63,10 @@ module GraphqlRails
57
63
  routes << build_route(MutationRoute, name, **options)
58
64
  end
59
65
 
66
+ def subscription(name, **options)
67
+ routes << build_route(SubscriptionRoute, name, **options)
68
+ end
69
+
60
70
  RAW_ACTION_NAMES.each do |action_name|
61
71
  define_method(action_name) do |*args, &block|
62
72
  add_raw_action(action_name, *args, &block)
@@ -64,30 +74,42 @@ module GraphqlRails
64
74
  end
65
75
 
66
76
  def graphql_schema(group = nil)
67
- @graphql_schema ||= {}
68
77
  @graphql_schema[group&.to_sym] ||= SchemaBuilder.new(
69
78
  queries: routes.select(&:query?),
70
79
  mutations: routes.select(&:mutation?),
80
+ subscriptions: routes.select(&:subscription?),
71
81
  raw_actions: raw_graphql_actions,
72
82
  group: group
73
83
  ).call
74
84
  end
75
85
 
76
86
  def reload_schema
77
- @graphql_schema = nil
87
+ @graphql_schema.clear
78
88
  end
79
89
 
80
90
  private
81
91
 
82
92
  attr_reader :module_name, :group_names
83
93
 
94
+ def router_with_scope_params(new_scope_name, **options)
95
+ new_scope_name ||= options[:path]
96
+
97
+ full_module_name = [module_name, options[:module]].select(&:present?).join('/')
98
+ full_scope_names = [*scope_names, new_scope_name].select(&:present?)
99
+
100
+ router_with(module_name: full_module_name, scope_names: full_scope_names)
101
+ end
102
+
84
103
  def router_with(new_router_options = {})
85
- default_options = { module_name: module_name, group_names: group_names }
86
- full_options = default_options.merge(new_router_options)
104
+ full_options = default_router_options.merge(new_router_options)
87
105
 
88
106
  self.class.new(**full_options)
89
107
  end
90
108
 
109
+ def default_router_options
110
+ { module_name: module_name, group_names: group_names, scope_names: scope_names }
111
+ end
112
+
91
113
  def add_raw_action(name, *args, &block)
92
114
  raw_graphql_actions << { name: name, args: args, block: block }
93
115
  end
@@ -105,7 +127,7 @@ module GraphqlRails
105
127
  end
106
128
 
107
129
  def default_route_options
108
- { module: module_name, on: :member }
130
+ { module: module_name, on: :member, scope_names: scope_names }
109
131
  end
110
132
  end
111
133
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphqlRails
4
- VERSION = '2.1.0'
4
+ VERSION = '2.3.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: 2.1.0
4
+ version: 2.3.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: 2022-01-12 00:00:00.000000000 Z
11
+ date: 2022-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -156,7 +156,6 @@ files:
156
156
  - docs/components/decorator.md
157
157
  - docs/components/model.md
158
158
  - docs/components/routes.md
159
- - docs/getting_started/quick_start.md
160
159
  - docs/getting_started/setup.md
161
160
  - docs/index.html
162
161
  - docs/logging_and_monitoring/logging_and_monitoring.md
@@ -220,12 +219,14 @@ files:
220
219
  - lib/graphql_rails/query_runner.rb
221
220
  - lib/graphql_rails/railtie.rb
222
221
  - lib/graphql_rails/router.rb
222
+ - lib/graphql_rails/router/build_schema_action_type.rb
223
223
  - lib/graphql_rails/router/mutation_route.rb
224
224
  - lib/graphql_rails/router/plain_cursor_encoder.rb
225
225
  - lib/graphql_rails/router/query_route.rb
226
226
  - lib/graphql_rails/router/resource_routes_builder.rb
227
227
  - lib/graphql_rails/router/route.rb
228
228
  - lib/graphql_rails/router/schema_builder.rb
229
+ - lib/graphql_rails/router/subscription_route.rb
229
230
  - lib/graphql_rails/rspec_controller_helpers.rb
230
231
  - lib/graphql_rails/tasks/dump_graphql_schema.rb
231
232
  - lib/graphql_rails/tasks/dump_graphql_schemas.rb
@@ -254,7 +255,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
254
255
  - !ruby/object:Gem::Version
255
256
  version: '0'
256
257
  requirements: []
257
- rubygems_version: 3.2.15
258
+ rubygems_version: 3.3.7
258
259
  signing_key:
259
260
  specification_version: 4
260
261
  summary: Rails style structure for GraphQL API.
@@ -1,62 +0,0 @@
1
- # Quick Start
2
-
3
- ## Generate initial code
4
-
5
- ```bash
6
- bundle exec rails g graphql_rails:install
7
- ```
8
-
9
- ## Define GraphQL schema as RoR routes
10
-
11
- ```ruby
12
- # config/graphql/routes.rb
13
- GraphqlRails::Router.draw do
14
- # will create createUser, updateUser, destroyUser mutations and user, users queries.
15
- # expects that UsersController class exist
16
- resources :users
17
-
18
- # if you want custom queries or mutation
19
- query 'searchLogs', to: 'logs#search' # redirects request to LogsController
20
- mutation 'changeUserPassword', to: 'users#change_password'
21
- end
22
- ```
23
-
24
- ## Define your Graphql model
25
-
26
- ```ruby
27
- class User # works with any class including ActiveRecord
28
- include GraphqlRails::Model
29
-
30
- graphql do |c|
31
- # most common attributes, like :id, :name, :title has default type, so you don't have to specify it (but you can!)
32
- c.attribute :id
33
-
34
- c.attribute :email, :string
35
- c.attribute :surname, :string
36
- end
37
- end
38
- ```
39
-
40
- ## Define controller
41
-
42
- ```ruby
43
- class UsersController < ApplicationGraphqlController
44
- # graphql requires to describe which attributes controller action accepts and which returns
45
- action(:change_user_password)
46
- .permit(:password!, :id!) # Bang (!) indicates that attribute is required
47
-
48
- def change_user_password
49
- user = User.find(params[:id])
50
- user.update!(password: params[:password])
51
-
52
- # returned value needs to have all methods defined in model `graphql do` part
53
- user # or SomeDecorator.new(user)
54
- end
55
-
56
- action(:search).permit(search_fields!: SearchFieldsInput) # you can specify your own input fields
57
- def search
58
- end
59
- end
60
- ```
61
-
62
- Congrats, you are done!