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.
- 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!
|