graphql_preload_queries 0.3.1 → 0.4.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 +2 -1
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +4 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +8 -4
- data/README.md +40 -44
- data/config/initializers/add_mutation_helper.rb +3 -3
- data/config/initializers/add_preload_field.rb +8 -0
- data/config/initializers/add_query_helper.rb +4 -4
- data/graphql_preload_queries.gemspec +1 -1
- data/lib/graphql_preload_queries/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fcc53358f8564b5b00d02cf7a341a7a82af9a9f02db2458fa4902f16d10847fb
|
4
|
+
data.tar.gz: 959b2a80b05637e60127762fae8fc765fff6c28c5438099cefbbe40c2c37a8c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12797d60fbcdb9d528a56563d29b22c14555de16f4d0e34d063efc48444ec9e0936e854f5cf4912b7575720b40f7f79bfee25ab0b13039f9276efad5b99591e1
|
7
|
+
data.tar.gz: 991bb3d2cf4c6a8ccc2df2ce26f48cf564d6a37c6bc5f4a68a0d8de8a6d8ae8c48b62a4595b800dd62f72dcca180a31f23e3c28d0025625e76dea6c1f758961d
|
data/.github/workflows/ruby.yml
CHANGED
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
@@ -8,6 +8,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
|
8
8
|
# Bundler will treat runtime dependencies like base dependencies, and
|
9
9
|
# development dependencies will be added by default to the :development group.
|
10
10
|
gemspec
|
11
|
+
gem 'byebug'
|
11
12
|
|
12
13
|
# Declare any dependencies that are still in development here instead of in
|
13
14
|
# your gemspec. These might include edge Rails or gems from your path or
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
graphql_preload_queries (0.
|
4
|
+
graphql_preload_queries (0.4.0)
|
5
5
|
graphql
|
6
6
|
rails
|
7
7
|
|
@@ -65,6 +65,7 @@ GEM
|
|
65
65
|
zeitwerk (~> 2.2, >= 2.2.2)
|
66
66
|
ast (2.4.1)
|
67
67
|
builder (3.2.4)
|
68
|
+
byebug (11.1.3)
|
68
69
|
concurrent-ruby (1.1.7)
|
69
70
|
crass (1.0.6)
|
70
71
|
database_cleaner (1.8.5)
|
@@ -86,11 +87,13 @@ GEM
|
|
86
87
|
marcel (0.3.3)
|
87
88
|
mimemagic (~> 0.3.2)
|
88
89
|
method_source (1.0.0)
|
89
|
-
mimemagic (0.3.
|
90
|
-
|
90
|
+
mimemagic (0.3.10)
|
91
|
+
nokogiri (~> 1)
|
92
|
+
rake
|
93
|
+
mini_mime (1.1.0)
|
91
94
|
mini_portile2 (2.4.0)
|
92
95
|
minitest (5.14.2)
|
93
|
-
nio4r (2.5.
|
96
|
+
nio4r (2.5.7)
|
94
97
|
nokogiri (1.10.10)
|
95
98
|
mini_portile2 (~> 2.4.0)
|
96
99
|
parallel (1.20.1)
|
@@ -183,6 +186,7 @@ PLATFORMS
|
|
183
186
|
ruby
|
184
187
|
|
185
188
|
DEPENDENCIES
|
189
|
+
byebug
|
186
190
|
database_cleaner-active_record
|
187
191
|
graphql_preload_queries!
|
188
192
|
rspec-rails
|
data/README.md
CHANGED
@@ -1,57 +1,51 @@
|
|
1
1
|
# GraphqlPreloadQueries
|
2
|
-
This gem
|
2
|
+
This gem permits your graphql application to define association preloads to improve app performance by removing N+1 query issues.
|
3
3
|
|
4
4
|
## Usage
|
5
5
|
* Object Type
|
6
6
|
```ruby
|
7
7
|
class UserType < Types::BaseObject
|
8
|
-
add_preload 'parents|allParents', { preload: :parents, friends: :friends, parents: :parents }
|
9
|
-
add_preload :friends, { parents: { preload: :parents, parents: :parents, friends: :friends } }
|
10
|
-
|
11
8
|
field :id, Int, null: true
|
12
9
|
field :name, String, null: true
|
13
|
-
field :
|
14
|
-
field :
|
10
|
+
field :parents, [Types::UserType], null: false, preload: true
|
11
|
+
field :friends, [Types::UserType], null: false, preload: :user_friends
|
15
12
|
end
|
16
13
|
```
|
17
|
-
Examples:
|
18
|
-
* ```add_preload(:friends)```
|
19
|
-
```:friends``` association will be preloaded if query includes ```friends```, like: ```user(id: 10) { friends { ... } }```
|
20
|
-
|
21
|
-
* ```add_preload(:allFriends, :friends)```
|
22
|
-
```:friends``` association will be preloaded if query includes ```allFriends```, like: ```user(id: 10) { allFriends { ... } }```
|
23
|
-
|
24
|
-
* ```add_preload(:allFriends, { preload: :friends, parents: :parents })```
|
25
|
-
```:preload``` key can be used to indicate the association name when defining nested preloads, like: ```user(id: 10) { allFriends { id parents { ... } } }```
|
26
14
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
15
|
+
`preload:` accepts:
|
16
|
+
- `true`: Will use field key as the association name
|
17
|
+
`field :parents, ..., preload: true` will preload `parents` association
|
18
|
+
- `Symbol`: Custom association name
|
19
|
+
`field :friends, ..., preload: :user_friends` will preload `user_friends` association
|
20
|
+
- `String`: Tied associations
|
21
|
+
`field :excluded_friends, ..., preload: 'excluded_friends.user'` will preload `excluded_friends -> user` association
|
22
|
+
- `Hash`: Deep preload definitions
|
23
|
+
`field :best_friends, ..., preload: { preload: :user_friends, parents: :parents }'`
|
24
|
+
* Will preload `user_friends` and `user_friends.parents` only if query includes inner definition, like `user(id: 10) { bestFriends { id parents { ... } } }`
|
25
|
+
* Will not preload `user_friends.parents` if query does not include inner definition, like `user(id: 10) { bestFriends { id } }`
|
26
|
+
|
38
27
|
|
39
28
|
* Preloads in query results
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
29
|
+
- BEFORE
|
30
|
+
```ruby
|
31
|
+
# queries/users.rb
|
32
|
+
def users(ids:)
|
33
|
+
users = User.where(id: ids)
|
34
|
+
end
|
35
|
+
```
|
36
|
+
Does not apply preloads to the root query.
|
37
|
+
- AFTER
|
38
|
+
```ruby
|
39
|
+
def users(ids:)
|
40
|
+
user = include_gql_preloads(User.where(id: id))
|
41
|
+
end
|
42
|
+
```
|
43
|
+
Root query applies all defined preloads
|
44
|
+
|
45
|
+
- `include_gql_preloads(collection, query_key: nil, type_klass: nil)`: Will include all preloads configured in `type_klass` (UserType) based on the gql query.
|
46
|
+
- `collection` (ActiveRecordCollection) Query results
|
47
|
+
- `query_key` (String | Sym, default: method name) Field result key
|
48
|
+
- `type_klass:` (GQL TypeClass, default: calculates using query_key)
|
55
49
|
|
56
50
|
* Preloads in mutation results
|
57
51
|
```ruby
|
@@ -60,12 +54,14 @@ This gem helps you to define all nested preloads to be added when required for g
|
|
60
54
|
field :users, [Types::UserType], null: true
|
61
55
|
def resolve(ids:)
|
62
56
|
affected_users = User.where(id: ids)
|
63
|
-
affected_users = include_gql_preloads(:users
|
64
|
-
puts affected_users.first&.friends # will print preloaded friends data
|
57
|
+
affected_users = include_gql_preloads(affected_users, query_key: :users)
|
65
58
|
{ users: affected_users }
|
66
59
|
end
|
67
60
|
```
|
68
|
-
- include_gql_preloads: Will
|
61
|
+
- `include_gql_preloads(collection, query_key: , type_klass: nil)`: Will include all preloads configured in `type_klass` (UserType) based on the gql query.
|
62
|
+
- `collection` (ActiveRecordCollection) Query results
|
63
|
+
- `query_key` (String | Sym) Field result key
|
64
|
+
- `type_klass:` (GQL TypeClass, default: calculates using query_key)
|
69
65
|
|
70
66
|
## Installation
|
71
67
|
Add this line to your application's Gemfile:
|
@@ -5,11 +5,11 @@ Rails.application.config.to_prepare do
|
|
5
5
|
GraphQL::Schema::Mutation.class_eval do
|
6
6
|
# TODO: auto recover type_klass using result key
|
7
7
|
# Add corresponding preloads to mutation results
|
8
|
-
# @param
|
8
|
+
# @param query_key (String | Sym)
|
9
9
|
# @param collection (ActiveCollection)
|
10
10
|
# @param type_klass (GQL TypeClass)
|
11
|
-
def include_gql_preloads(
|
12
|
-
gql_result_key = GraphQL::Schema::Member::BuildType.camelize(
|
11
|
+
def include_gql_preloads(collection, query_key:, type_klass: nil)
|
12
|
+
gql_result_key = GraphQL::Schema::Member::BuildType.camelize(query_key.to_s)
|
13
13
|
type_klass ||= preload_type_klass(gql_result_key.to_s)
|
14
14
|
klass = GraphqlPreloadQueries::Extensions::Preload
|
15
15
|
ast_node = preload_find_node(gql_result_key)
|
@@ -31,6 +31,14 @@ Rails.application.config.to_prepare do
|
|
31
31
|
key = GraphQL::Schema::Member::BuildType.camelize(key.to_s)
|
32
32
|
preloads[key] = preload
|
33
33
|
end
|
34
|
+
|
35
|
+
alias_method :field_old, :field
|
36
|
+
def field(*args, **kwargs, &block)
|
37
|
+
preload = kwargs.delete(:preload)
|
38
|
+
key = args[0]
|
39
|
+
add_preload(key, preload == true ? key : preload) if preload
|
40
|
+
field_old(*args, **kwargs, &block)
|
41
|
+
end
|
34
42
|
end
|
35
43
|
end
|
36
44
|
end
|
@@ -3,14 +3,14 @@
|
|
3
3
|
# preload resolver for queries
|
4
4
|
Rails.application.config.to_prepare do
|
5
5
|
Types::QueryType.class_eval do
|
6
|
-
# TODO: auto recover type_klass using result key
|
7
6
|
# Add corresponding preloads to query results
|
8
7
|
# Note: key is automatically calculated based on method name
|
9
|
-
# @param gql_result_key (String | Sym)
|
10
8
|
# @param collection (ActiveCollection)
|
11
9
|
# @param type_klass (GQL TypeClass, default: calculates using return type)
|
12
|
-
|
13
|
-
|
10
|
+
# @param query_key (String | Sym) Default method name
|
11
|
+
def include_gql_preloads(collection, query_key: nil, type_klass: nil)
|
12
|
+
query_key ||= caller_locations(1, 1)[0].label
|
13
|
+
gql_result_key = GraphQL::Schema::Member::BuildType.camelize(query_key.to_s)
|
14
14
|
type_klass ||= preload_type_klass(gql_result_key.to_s)
|
15
15
|
klass = GraphqlPreloadQueries::Extensions::Preload
|
16
16
|
ast_node = preload_find_node(gql_result_key)
|
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.description = 'Permit to avoid N+1 queries problem when using graphql queries'
|
14
14
|
spec.homepage = 'https://github.com/owen2345/graphql_preload_queries'
|
15
15
|
spec.license = 'MIT'
|
16
|
-
spec.required_ruby_version = Gem::Requirement.new('>= 2.
|
16
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.0') # rubocop:disable Gemspec/RequiredRubyVersion
|
17
17
|
|
18
18
|
# spec.metadata["allowed_push_host"] = ""
|
19
19
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql_preload_queries
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- owen2345
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -154,7 +154,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
154
154
|
requirements:
|
155
155
|
- - ">="
|
156
156
|
- !ruby/object:Gem::Version
|
157
|
-
version: 2.
|
157
|
+
version: '2.0'
|
158
158
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
159
159
|
requirements:
|
160
160
|
- - ">="
|