graphql_rails 2.1.0 → 2.3.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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +1 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +14 -0
- data/Gemfile.lock +117 -116
- data/docs/README.md +23 -45
- data/docs/_sidebar.md +0 -1
- data/docs/components/controller.md +15 -1
- data/docs/components/decorator.md +1 -1
- data/docs/components/model.md +62 -0
- data/docs/components/routes.md +45 -8
- data/lib/graphql_rails/attributes/attribute.rb +8 -14
- data/lib/graphql_rails/attributes/attribute_configurable.rb +15 -0
- data/lib/graphql_rails/attributes/input_attribute.rb +17 -1
- data/lib/graphql_rails/attributes/type_parseable.rb +1 -7
- data/lib/graphql_rails/controller/build_controller_action_resolver.rb +2 -0
- data/lib/graphql_rails/controller/log_controller_action.rb +7 -2
- data/lib/graphql_rails/controller.rb +1 -1
- data/lib/graphql_rails/decorator/relation_decorator.rb +22 -18
- data/lib/graphql_rails/decorator.rb +12 -4
- data/lib/graphql_rails/errors/system_error.rb +11 -1
- data/lib/graphql_rails/errors/validation_error.rb +14 -1
- data/lib/graphql_rails/input_configurable.rb +1 -1
- data/lib/graphql_rails/model/find_or_build_graphql_type.rb +1 -5
- data/lib/graphql_rails/router/build_schema_action_type.rb +112 -0
- data/lib/graphql_rails/router/mutation_route.rb +4 -0
- data/lib/graphql_rails/router/query_route.rb +4 -0
- data/lib/graphql_rails/router/resource_routes_builder.rb +8 -0
- data/lib/graphql_rails/router/route.rb +3 -2
- data/lib/graphql_rails/router/schema_builder.rb +14 -18
- data/lib/graphql_rails/router/subscription_route.rb +22 -0
- data/lib/graphql_rails/router.rb +32 -10
- data/lib/graphql_rails/version.rb +1 -1
- metadata +5 -4
- 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 =
|
43
|
-
|
46
|
+
group_routes =
|
47
|
+
routes
|
48
|
+
.select { |route| route.show_in_group?(group_name) }
|
49
|
+
.reverse
|
50
|
+
.uniq(&:name)
|
51
|
+
.reverse
|
44
52
|
|
45
|
-
|
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
|
-
|
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
|
data/lib/graphql_rails/router.rb
CHANGED
@@ -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
|
-
|
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
|
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
|
-
|
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
|
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.
|
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-
|
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.
|
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!
|