graphql-persisted_queries 1.0.1 → 1.2.1
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/rspec.yml +53 -0
- data/.github/workflows/rubocop.yml +21 -0
- data/CHANGELOG.md +24 -2
- data/README.md +15 -2
- data/Rakefile +29 -1
- data/benchmark/compiled_queries.rb +41 -0
- data/benchmark/helpers.rb +31 -0
- data/benchmark/persisted_queries.rb +41 -0
- data/benchmark/plain_gql.rb +33 -0
- data/docs/compiled_queries_benchmark.md +75 -0
- data/gemfiles/{graphql_1_8.gemfile → graphql_1_11.gemfile} +1 -1
- data/gemfiles/{graphql_1_9.gemfile → graphql_1_12_0.gemfile} +1 -1
- data/gemfiles/graphql_1_12_4.gemfile +5 -0
- data/graphql-persisted_queries.gemspec +1 -1
- data/lib/graphql/persisted_queries.rb +26 -3
- data/lib/graphql/persisted_queries/compiled_queries/multiplex_patch.rb +30 -0
- data/lib/graphql/persisted_queries/compiled_queries/query_patch.rb +33 -0
- data/lib/graphql/persisted_queries/compiled_queries/resolver.rb +38 -0
- data/lib/graphql/persisted_queries/error_handlers.rb +4 -4
- data/lib/graphql/persisted_queries/error_handlers/base_error_handler.rb +1 -1
- data/lib/graphql/persisted_queries/errors.rb +19 -0
- data/lib/graphql/persisted_queries/multiplex_resolver.rb +5 -4
- data/lib/graphql/persisted_queries/resolver.rb +11 -33
- data/lib/graphql/persisted_queries/resolver_helpers.rb +26 -0
- data/lib/graphql/persisted_queries/schema_patch.rb +31 -22
- data/lib/graphql/persisted_queries/store_adapters.rb +4 -4
- data/lib/graphql/persisted_queries/store_adapters/base_store_adapter.rb +15 -5
- data/lib/graphql/persisted_queries/store_adapters/memcached_store_adapter.rb +1 -1
- data/lib/graphql/persisted_queries/store_adapters/memory_store_adapter.rb +1 -1
- data/lib/graphql/persisted_queries/store_adapters/redis_store_adapter.rb +1 -1
- data/lib/graphql/persisted_queries/version.rb +1 -1
- metadata +23 -11
- data/.travis.yml +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ae3a956abf426513fde7370b4e90e4677b227a43a800a67e0094e05439a06a1
|
4
|
+
data.tar.gz: 918f9fd46776d26a849cf858f4b791594ce694702cbae5f453672829c070f0fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69a31f10dd9e701fd7b00e28f40e4a51abc3b78d8d7a76bc0c670dd8c5a9fd4ef87b8e2df65d5128a092a636855b4c8940fbe0f8ba25d4136e8cc7c3200d7d80
|
7
|
+
data.tar.gz: 11352cf7e1ec1e5d02e3445bc59598971e62bb5937964c31dc9e6d6883960f0b79c1895afbab231e7c0c61f2de211653f208326d880d07d9e5b67c7713681bbb
|
@@ -0,0 +1,53 @@
|
|
1
|
+
name: RSpec
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
schedule:
|
9
|
+
- cron: "0 10 * * *"
|
10
|
+
|
11
|
+
jobs:
|
12
|
+
rspec:
|
13
|
+
runs-on: ubuntu-latest
|
14
|
+
|
15
|
+
env:
|
16
|
+
CI: true
|
17
|
+
|
18
|
+
strategy:
|
19
|
+
fail-fast: false
|
20
|
+
matrix:
|
21
|
+
ruby: [2.3, 2.4, 2.5, 2.6, 2.7]
|
22
|
+
gemfile: [
|
23
|
+
"gemfiles/graphql_1_10.gemfile",
|
24
|
+
"gemfiles/graphql_1_11.gemfile",
|
25
|
+
"gemfiles/graphql_1_12_0.gemfile",
|
26
|
+
"gemfiles/graphql_1_12_4.gemfile",
|
27
|
+
"gemfiles/graphql_master.gemfile"
|
28
|
+
]
|
29
|
+
|
30
|
+
steps:
|
31
|
+
- uses: actions/checkout@v2
|
32
|
+
- uses: actions/cache@v2
|
33
|
+
with:
|
34
|
+
path: /home/runner/bundle
|
35
|
+
key: bundle-${{ matrix.ruby }}-${{ matrix.gemfile }}-${{ hashFiles(matrix.gemfile) }}-${{ hashFiles('**/*.gemspec') }}
|
36
|
+
restore-keys: |
|
37
|
+
bundle-${{ matrix.ruby }}-${{ matrix.gemfile }}-
|
38
|
+
- uses: ruby/setup-ruby@v1
|
39
|
+
with:
|
40
|
+
ruby-version: ${{ matrix.ruby }}
|
41
|
+
- name: Install system deps
|
42
|
+
run: |
|
43
|
+
sudo apt-get update
|
44
|
+
sudo apt-get install libsqlite3-dev
|
45
|
+
- name: Bundle install
|
46
|
+
run: |
|
47
|
+
bundle config path /home/runner/bundle
|
48
|
+
bundle config --global gemfile ${{ matrix.gemfile }}
|
49
|
+
bundle install
|
50
|
+
bundle update
|
51
|
+
- name: Run RSpec
|
52
|
+
run: |
|
53
|
+
bundle exec rake ci_specs
|
@@ -0,0 +1,21 @@
|
|
1
|
+
name: Rubocop
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
rubocop:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
|
13
|
+
steps:
|
14
|
+
- uses: actions/checkout@v2
|
15
|
+
- uses: ruby/setup-ruby@v1
|
16
|
+
with:
|
17
|
+
ruby-version: 2.7
|
18
|
+
- name: Lint Ruby code with RuboCop
|
19
|
+
run: |
|
20
|
+
bundle install --gemfile gemfiles/graphql_1_10.gemfile --jobs 4 --retry 3
|
21
|
+
bundle exec --gemfile gemfiles/graphql_1_10.gemfile rubocop
|
data/CHANGELOG.md
CHANGED
@@ -2,9 +2,30 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
-
##
|
5
|
+
## 1.2.1 (2021-03-07)
|
6
6
|
|
7
|
-
- [PR#
|
7
|
+
- [PR#43](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/43) Properly handle configuration when schema is inherited ([@DmitryTsepelev][])
|
8
|
+
- [PR#44](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/44) Deprecate graphql-ruby 1.8 and 1.9 ([@DmitryTsepelev][])
|
9
|
+
|
10
|
+
## 1.2.0 (2021-02-24)
|
11
|
+
|
12
|
+
- [PR#39](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/39) Implement compiled queries ([@DmitryTsepelev][])
|
13
|
+
|
14
|
+
## 1.1.1 (2020-12-03)
|
15
|
+
|
16
|
+
- [PR#37](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/37) Fix deprecation warnings ([@rbviz][])
|
17
|
+
|
18
|
+
## 1.1.0 (2020-11-16)
|
19
|
+
|
20
|
+
- [PR#36](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/36) Support Ruby 2.7.0 ([@DmitryTsepelev][])
|
21
|
+
|
22
|
+
## 1.0.2 (2020-06-29)
|
23
|
+
|
24
|
+
- [PR#35](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/35) fix args for GraphQL::Query::Result ([@ogidow][])
|
25
|
+
|
26
|
+
## 1.0.1 (2020-06-25)
|
27
|
+
|
28
|
+
- [PR#34](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/34) Return GraphQL::Query::Result when raise error ([@ogidow][])
|
8
29
|
|
9
30
|
## 🥳 1.0.0 (2020-03-31)
|
10
31
|
|
@@ -52,3 +73,4 @@
|
|
52
73
|
[@bmorton]: https://github.com/bmorton
|
53
74
|
[@JanStevens]: https://github.com/JanStevens
|
54
75
|
[@ogidow]: https://github.com/ogidow
|
76
|
+
[@rbviz]: https://github.com/rbviz
|
data/README.md
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
# GraphQL::PersistedQueries
|
2
|
-
|
1
|
+
# GraphQL::PersistedQueries
|
3
2
|
|
4
3
|
`GraphQL::PersistedQueries` is the implementation of [persisted queries](https://github.com/apollographql/apollo-link-persisted-queries) for [graphql-ruby](https://github.com/rmosolgo/graphql-ruby). With this plugin your backend will cache all the queries, while frontend will send the full query only when it's not found at the backend storage.
|
5
4
|
|
@@ -66,6 +65,20 @@ GraphqlSchema.execute(
|
|
66
65
|
|
67
66
|
You're all set!
|
68
67
|
|
68
|
+
## Compiled queries (increases performance up to 2x!)
|
69
|
+
|
70
|
+
When query arrives to the backend, GraphQL execution engine needs some time to _parse_ it and build the AST. In case of a huge query it might take [a lot](https://gist.github.com/DmitryTsepelev/36e290cf64b4ec0b18294d0a57fb26ff#file-1_result-md) of time. What if we cache the AST instead of a query text and skip parsing completely? The only thing you need to do is to turn `:compiled_queries` option on:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
class GraphqlSchema < GraphQL::Schema
|
74
|
+
use GraphQL::PersistedQueries, compiled_queries: true
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
78
|
+
Using this option might make your endpoint up to 2x faster according to the [benchmark](docs/compiled_queries_benchmark.md).
|
79
|
+
|
80
|
+
**Heads up!** This feature only works on `graphql-ruby` 1.12.0 or later, but I guess it might be backported.
|
81
|
+
|
69
82
|
## Advanced usage
|
70
83
|
|
71
84
|
All the queries are stored in memory by default, but you can easily switch to another storage (e.g., _redis_:
|
data/Rakefile
CHANGED
@@ -5,4 +5,32 @@ require "rubocop/rake_task"
|
|
5
5
|
RSpec::Core::RakeTask.new(:spec)
|
6
6
|
RuboCop::RakeTask.new
|
7
7
|
|
8
|
-
|
8
|
+
desc "Run specs for compiled queries"
|
9
|
+
RSpec::Core::RakeTask.new("spec:compiled_queries") do |task|
|
10
|
+
task.pattern = "**/compiled_queries/**"
|
11
|
+
task.verbose = false
|
12
|
+
end
|
13
|
+
|
14
|
+
RSpec::Core::RakeTask.new("spec:without_compiled_queries") do |task|
|
15
|
+
task.exclude_pattern = "**/compiled_queries/**"
|
16
|
+
task.verbose = false
|
17
|
+
end
|
18
|
+
|
19
|
+
task ci_specs: ["spec:without_compiled_queries", "spec:compiled_queries"]
|
20
|
+
|
21
|
+
task :bench_gql do
|
22
|
+
cmd = %w[bundle exec ruby benchmark/plain_gql.rb]
|
23
|
+
system(*cmd)
|
24
|
+
end
|
25
|
+
|
26
|
+
task :bench_pq do
|
27
|
+
cmd = %w[bundle exec ruby benchmark/persisted_queries.rb]
|
28
|
+
system(*cmd)
|
29
|
+
end
|
30
|
+
|
31
|
+
task :bench_compiled do
|
32
|
+
cmd = %w[bundle exec ruby benchmark/compiled_queries.rb]
|
33
|
+
system(*cmd)
|
34
|
+
end
|
35
|
+
|
36
|
+
task bench: [:bench_gql, :bench_pq, :bench_compiled]
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "bundler/inline"
|
2
|
+
|
3
|
+
gemfile do
|
4
|
+
source "https://rubygems.org"
|
5
|
+
gem "graphql", "1.12.4"
|
6
|
+
end
|
7
|
+
|
8
|
+
$:.push File.expand_path("../lib", __dir__)
|
9
|
+
|
10
|
+
require "benchmark"
|
11
|
+
require "graphql/persisted_queries"
|
12
|
+
require_relative "helpers"
|
13
|
+
|
14
|
+
class GraphqlSchema < GraphQL::Schema
|
15
|
+
use GraphQL::PersistedQueries, compiled_queries: true
|
16
|
+
|
17
|
+
query QueryType
|
18
|
+
end
|
19
|
+
|
20
|
+
GraphqlSchema.to_definition
|
21
|
+
|
22
|
+
puts
|
23
|
+
puts "Schema with compiled queries:"
|
24
|
+
puts
|
25
|
+
|
26
|
+
Benchmark.bm(28) do |x|
|
27
|
+
[false, true].each do |with_nested|
|
28
|
+
FIELD_COUNTS.each do |field_count|
|
29
|
+
query = generate_query(field_count, with_nested)
|
30
|
+
sha256 = Digest::SHA256.hexdigest(query)
|
31
|
+
|
32
|
+
context = { extensions: { "persistedQuery" => { "sha256Hash" => sha256 } } }
|
33
|
+
# warmup
|
34
|
+
GraphqlSchema.execute(query, context: context)
|
35
|
+
|
36
|
+
x.report("#{field_count} fields#{" (nested)" if with_nested}") do
|
37
|
+
GraphqlSchema.execute(query, context: context)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
FIELD_COUNTS = [10, 50, 100, 200, 300]
|
2
|
+
|
3
|
+
def generate_fields(field_count, with_nested)
|
4
|
+
fields = field_count.times.map do |i|
|
5
|
+
field = "field#{i+1}"
|
6
|
+
field += "\s{#{generate_fields(field_count, false)}}" if with_nested
|
7
|
+
field
|
8
|
+
end
|
9
|
+
|
10
|
+
fields.join("\n")
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate_query(field_count, with_nested)
|
14
|
+
<<-gql
|
15
|
+
query {
|
16
|
+
#{generate_fields(field_count, with_nested)}
|
17
|
+
}
|
18
|
+
gql
|
19
|
+
end
|
20
|
+
|
21
|
+
class ChildType < GraphQL::Schema::Object
|
22
|
+
FIELD_COUNTS.max.times do |i|
|
23
|
+
field "field#{i + 1}".to_sym, String, null: false, method: :itself
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class QueryType < GraphQL::Schema::Object
|
28
|
+
FIELD_COUNTS.max.times do |i|
|
29
|
+
field "field#{i + 1}".to_sym, ChildType, null: false, method: :itself
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "bundler/inline"
|
2
|
+
|
3
|
+
gemfile do
|
4
|
+
source "https://rubygems.org"
|
5
|
+
gem "graphql", "1.12.4"
|
6
|
+
end
|
7
|
+
|
8
|
+
$:.push File.expand_path("../lib", __dir__)
|
9
|
+
|
10
|
+
require "benchmark"
|
11
|
+
require "graphql/persisted_queries"
|
12
|
+
require_relative "helpers"
|
13
|
+
|
14
|
+
class GraphqlSchema < GraphQL::Schema
|
15
|
+
use GraphQL::PersistedQueries
|
16
|
+
|
17
|
+
query QueryType
|
18
|
+
end
|
19
|
+
|
20
|
+
GraphqlSchema.to_definition
|
21
|
+
|
22
|
+
puts
|
23
|
+
puts "Schema with persisted queries:"
|
24
|
+
puts
|
25
|
+
|
26
|
+
Benchmark.bm(28) do |x|
|
27
|
+
[false, true].each do |with_nested|
|
28
|
+
FIELD_COUNTS.each do |field_count|
|
29
|
+
query = generate_query(field_count, with_nested)
|
30
|
+
sha256 = Digest::SHA256.hexdigest(query)
|
31
|
+
context = { extensions: { "persistedQuery" => { "sha256Hash" => sha256 } } }
|
32
|
+
|
33
|
+
# warmup
|
34
|
+
GraphqlSchema.execute(query, context: context)
|
35
|
+
|
36
|
+
x.report("#{field_count} fields#{" (nested)" if with_nested}") do
|
37
|
+
GraphqlSchema.execute(query, context: context)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "bundler/inline"
|
2
|
+
|
3
|
+
gemfile do
|
4
|
+
source "https://rubygems.org"
|
5
|
+
gem "graphql", "1.12.4"
|
6
|
+
end
|
7
|
+
|
8
|
+
$:.push File.expand_path("../lib", __dir__)
|
9
|
+
|
10
|
+
require "benchmark"
|
11
|
+
require "graphql/persisted_queries"
|
12
|
+
require_relative "helpers"
|
13
|
+
|
14
|
+
class GraphqlSchema < GraphQL::Schema
|
15
|
+
query QueryType
|
16
|
+
end
|
17
|
+
|
18
|
+
GraphqlSchema.to_definition
|
19
|
+
|
20
|
+
puts "Plain schema:"
|
21
|
+
puts
|
22
|
+
|
23
|
+
Benchmark.bm(28) do |x|
|
24
|
+
[false, true].each do |with_nested|
|
25
|
+
FIELD_COUNTS.each do |field_count|
|
26
|
+
query = generate_query(field_count, with_nested)
|
27
|
+
|
28
|
+
x.report("#{field_count} fields#{" (nested)" if with_nested}") do
|
29
|
+
GraphqlSchema.execute(query)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# Compiled queries benchmarks
|
2
|
+
|
3
|
+
The name of benchmark consists of a field count and optional "nested" label. In case of non–nested one we just generate a query with that field count, e.g. `2 fields` means:
|
4
|
+
|
5
|
+
```gql
|
6
|
+
query {
|
7
|
+
field1
|
8
|
+
field2
|
9
|
+
}
|
10
|
+
```
|
11
|
+
|
12
|
+
In case of "nested" benchmark we also put a list of fields to each top–level field, e.g. `2 fields (nested)` means:
|
13
|
+
|
14
|
+
```gql
|
15
|
+
query {
|
16
|
+
field1 {
|
17
|
+
field1
|
18
|
+
field2
|
19
|
+
}
|
20
|
+
field2 {
|
21
|
+
field1
|
22
|
+
field2
|
23
|
+
}
|
24
|
+
}
|
25
|
+
```
|
26
|
+
|
27
|
+
Field resolver just returns a string, so real–world tests might be way slower because of IO.
|
28
|
+
|
29
|
+
Here are the results:
|
30
|
+
|
31
|
+
```
|
32
|
+
Plain schema:
|
33
|
+
|
34
|
+
user system total real
|
35
|
+
10 fields 0.001061 0.000039 0.001100 ( 0.001114)
|
36
|
+
50 fields 0.001658 0.000003 0.001661 ( 0.001661)
|
37
|
+
100 fields 0.004587 0.000026 0.004613 ( 0.004614)
|
38
|
+
200 fields 0.006447 0.000016 0.006463 ( 0.006476)
|
39
|
+
300 fields 0.024493 0.000073 0.024566 ( 0.024614)
|
40
|
+
10 fields (nested) 0.003061 0.000043 0.003104 ( 0.003109)
|
41
|
+
50 fields (nested) 0.056927 0.000995 0.057922 ( 0.057997)
|
42
|
+
100 fields (nested) 0.245235 0.001336 0.246571 ( 0.246727)
|
43
|
+
200 fields (nested) 0.974444 0.006531 0.980975 ( 0.981810)
|
44
|
+
300 fields (nested) 2.175855 0.012773 2.188628 ( 2.190130)
|
45
|
+
|
46
|
+
Schema with persisted queries:
|
47
|
+
|
48
|
+
user system total real
|
49
|
+
10 fields 0.000606 0.000007 0.000613 ( 0.000607)
|
50
|
+
50 fields 0.001855 0.000070 0.001925 ( 0.001915)
|
51
|
+
100 fields 0.003239 0.000009 0.003248 ( 0.003239)
|
52
|
+
200 fields 0.007542 0.000009 0.007551 ( 0.007551)
|
53
|
+
300 fields 0.014975 0.000237 0.015212 ( 0.015318)
|
54
|
+
10 fields (nested) 0.002992 0.000068 0.003060 ( 0.003049)
|
55
|
+
50 fields (nested) 0.062314 0.000274 0.062588 ( 0.062662)
|
56
|
+
100 fields (nested) 0.256404 0.000865 0.257269 ( 0.257419)
|
57
|
+
200 fields (nested) 0.978408 0.007437 0.985845 ( 0.986579)
|
58
|
+
300 fields (nested) 2.263338 0.010994 2.274332 ( 2.275967)
|
59
|
+
|
60
|
+
Schema with compiled queries:
|
61
|
+
|
62
|
+
user system total real
|
63
|
+
10 fields 0.000526 0.000009 0.000535 ( 0.000530)
|
64
|
+
50 fields 0.001280 0.000012 0.001292 ( 0.001280)
|
65
|
+
100 fields 0.002292 0.000004 0.002296 ( 0.002286)
|
66
|
+
200 fields 0.005462 0.000001 0.005463 ( 0.005463)
|
67
|
+
300 fields 0.014229 0.000121 0.014350 ( 0.014348)
|
68
|
+
10 fields (nested) 0.002027 0.000069 0.002096 ( 0.002104)
|
69
|
+
50 fields (nested) 0.029933 0.000087 0.030020 ( 0.030040)
|
70
|
+
100 fields (nested) 0.133933 0.000502 0.134435 ( 0.134756)
|
71
|
+
200 fields (nested) 0.495052 0.003545 0.498597 ( 0.499452)
|
72
|
+
300 fields (nested) 1.041463 0.005130 1.046593 ( 1.047137)
|
73
|
+
```
|
74
|
+
|
75
|
+
Results gathered from my MacBook Pro Mid 2014 (2,5 GHz Quad-Core Intel Core i7, 16 GB 1600 MHz DDR3).
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.required_ruby_version = ">= 2.3"
|
24
24
|
|
25
|
-
spec.add_dependency "graphql", ">= 1.
|
25
|
+
spec.add_dependency "graphql", ">= 1.10"
|
26
26
|
|
27
27
|
spec.add_development_dependency "rspec", "~> 3.9"
|
28
28
|
spec.add_development_dependency "rake", ">= 10.0"
|
@@ -1,17 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "graphql/persisted_queries/resolver_helpers"
|
4
|
+
require "graphql/persisted_queries/errors"
|
3
5
|
require "graphql/persisted_queries/error_handlers"
|
4
6
|
require "graphql/persisted_queries/schema_patch"
|
5
7
|
require "graphql/persisted_queries/store_adapters"
|
6
8
|
require "graphql/persisted_queries/version"
|
7
9
|
require "graphql/persisted_queries/builder_helpers"
|
8
10
|
|
11
|
+
require "graphql/persisted_queries/compiled_queries/resolver"
|
12
|
+
require "graphql/persisted_queries/compiled_queries/multiplex_patch"
|
13
|
+
require "graphql/persisted_queries/compiled_queries/query_patch"
|
14
|
+
|
9
15
|
module GraphQL
|
10
16
|
# Plugin definition
|
11
17
|
module PersistedQueries
|
12
|
-
|
18
|
+
# rubocop:disable Metrics/MethodLength
|
19
|
+
def self.use(schema_defn, **options)
|
13
20
|
schema = schema_defn.is_a?(Class) ? schema_defn : schema_defn.target
|
14
|
-
|
21
|
+
|
22
|
+
compiled_queries = options.delete(:compiled_queries)
|
23
|
+
SchemaPatch.patch(schema, compiled_queries)
|
24
|
+
configure_compiled_queries if compiled_queries
|
15
25
|
|
16
26
|
schema.hash_generator = options.delete(:hash_generator) || :sha256
|
17
27
|
|
@@ -23,7 +33,20 @@ module GraphQL
|
|
23
33
|
schema.persisted_queries_tracing_enabled = options.delete(:tracing)
|
24
34
|
|
25
35
|
store = options.delete(:store) || :memory
|
26
|
-
schema.configure_persisted_query_store(store, options)
|
36
|
+
schema.configure_persisted_query_store(store, **options)
|
37
|
+
end
|
38
|
+
# rubocop:enable Metrics/MethodLength
|
39
|
+
|
40
|
+
def self.configure_compiled_queries
|
41
|
+
if Gem::Dependency.new("graphql", "< 1.12.0").match?("graphql", GraphQL::VERSION)
|
42
|
+
raise ArgumentError, "compiled_queries are not supported for graphql-ruby < 1.12.0"
|
43
|
+
end
|
44
|
+
|
45
|
+
GraphQL::Execution::Multiplex.singleton_class.prepend(
|
46
|
+
GraphQL::PersistedQueries::CompiledQueries::MultiplexPatch
|
47
|
+
)
|
48
|
+
|
49
|
+
GraphQL::Query.prepend(GraphQL::PersistedQueries::CompiledQueries::QueryPatch)
|
27
50
|
end
|
28
51
|
end
|
29
52
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module PersistedQueries
|
5
|
+
module CompiledQueries
|
6
|
+
# Patches GraphQL::Execution::Multiplex to support compiled queries
|
7
|
+
module MultiplexPatch
|
8
|
+
if Gem::Dependency.new("graphql", ">= 1.12.4").match?("graphql", GraphQL::VERSION)
|
9
|
+
def begin_query(results, idx, query, multiplex)
|
10
|
+
return super unless query.persisted_query_not_found?
|
11
|
+
|
12
|
+
results[idx] = add_not_found_error(query)
|
13
|
+
end
|
14
|
+
else
|
15
|
+
def begin_query(query, multiplex)
|
16
|
+
return super unless query.persisted_query_not_found?
|
17
|
+
|
18
|
+
add_not_found_error(query)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_not_found_error(query)
|
23
|
+
query.context.errors.clear
|
24
|
+
query.context.errors << GraphQL::ExecutionError.new("PersistedQueryNotFound")
|
25
|
+
GraphQL::Execution::Multiplex::NO_OPERATION
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module PersistedQueries
|
5
|
+
module CompiledQueries
|
6
|
+
# Patches GraphQL::Query to support compiled queries
|
7
|
+
module QueryPatch
|
8
|
+
def persisted_query_not_found?
|
9
|
+
@persisted_query_not_found
|
10
|
+
end
|
11
|
+
|
12
|
+
def prepare_ast
|
13
|
+
return super unless @context[:extensions]
|
14
|
+
|
15
|
+
@document = resolver.fetch
|
16
|
+
not_loaded_document = @document.nil?
|
17
|
+
|
18
|
+
@persisted_query_not_found = not_loaded_document && query_string.nil?
|
19
|
+
|
20
|
+
super.tap do
|
21
|
+
resolver.persist(query_string, @document) if not_loaded_document && query_string
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def resolver
|
28
|
+
@resolver ||= Resolver.new(@schema, @context[:extensions])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module PersistedQueries
|
5
|
+
module CompiledQueries
|
6
|
+
# Fetches and persists compiled query
|
7
|
+
class Resolver
|
8
|
+
include GraphQL::PersistedQueries::ResolverHelpers
|
9
|
+
|
10
|
+
def initialize(schema, extensions)
|
11
|
+
@schema = schema
|
12
|
+
@extensions = extensions
|
13
|
+
end
|
14
|
+
|
15
|
+
def fetch
|
16
|
+
return if hash.nil?
|
17
|
+
|
18
|
+
with_error_handling do
|
19
|
+
compiled_query = @schema.persisted_query_store.fetch_query(hash, compiled_query: true)
|
20
|
+
Marshal.load(compiled_query) if compiled_query # rubocop:disable Security/MarshalLoad
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def persist(query_string, compiled_query)
|
25
|
+
return if hash.nil?
|
26
|
+
|
27
|
+
validate_hash!(query_string)
|
28
|
+
|
29
|
+
with_error_handling do
|
30
|
+
@schema.persisted_query_store.save_query(
|
31
|
+
hash, Marshal.dump(compiled_query), compiled_query: true
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -7,13 +7,13 @@ module GraphQL
|
|
7
7
|
module PersistedQueries
|
8
8
|
# Contains factory methods for error handlers
|
9
9
|
module ErrorHandlers
|
10
|
-
def self.build(handler, options
|
10
|
+
def self.build(handler, **options)
|
11
11
|
if handler.is_a?(ErrorHandlers::BaseErrorHandler)
|
12
12
|
handler
|
13
13
|
elsif handler.is_a?(Proc)
|
14
14
|
build_from_proc(handler)
|
15
15
|
else
|
16
|
-
build_by_name(handler, options)
|
16
|
+
build_by_name(handler, **options)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -25,8 +25,8 @@ module GraphQL
|
|
25
25
|
proc
|
26
26
|
end
|
27
27
|
|
28
|
-
def self.build_by_name(name, options)
|
29
|
-
const_get("#{BuilderHelpers.camelize(name)}ErrorHandler").new(options
|
28
|
+
def self.build_by_name(name, **options)
|
29
|
+
const_get("#{BuilderHelpers.camelize(name)}ErrorHandler").new(**options)
|
30
30
|
rescue NameError => e
|
31
31
|
raise e.class, "Persisted query error handler for :#{name} haven't been found", e.backtrace
|
32
32
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module PersistedQueries
|
5
|
+
# Raised when persisted query is not found in the storage
|
6
|
+
class NotFound < StandardError
|
7
|
+
def message
|
8
|
+
"PersistedQueryNotFound"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Raised when provided hash is not matched with query
|
13
|
+
class WrongHash < StandardError
|
14
|
+
def message
|
15
|
+
"Wrong hash was passed"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -4,7 +4,7 @@ module GraphQL
|
|
4
4
|
module PersistedQueries
|
5
5
|
# Resolves multiplex query
|
6
6
|
class MultiplexResolver
|
7
|
-
def initialize(schema, queries, kwargs)
|
7
|
+
def initialize(schema, queries, **kwargs)
|
8
8
|
@schema = schema
|
9
9
|
@queries = queries
|
10
10
|
@kwargs = kwargs
|
@@ -33,15 +33,16 @@ module GraphQL
|
|
33
33
|
return unless extensions
|
34
34
|
|
35
35
|
query_params[:query] = Resolver.new(extensions, @schema).resolve(query_params[:query])
|
36
|
-
rescue
|
36
|
+
rescue GraphQL::PersistedQueries::NotFound, GraphQL::PersistedQueries::WrongHash => e
|
37
37
|
values = { "errors" => [{ "message" => e.message }] }
|
38
|
-
|
38
|
+
query = GraphQL::Query.new(@schema, query_params[:query])
|
39
|
+
results[pos] = GraphQL::Query::Result.new(query: query, values: values)
|
39
40
|
end
|
40
41
|
|
41
42
|
def perform_multiplex
|
42
43
|
resolve_idx = (0...@queries.count).select { |i| results[i].nil? }
|
43
44
|
multiplex_result = @schema.multiplex_original(
|
44
|
-
resolve_idx.map { |i| @queries.at(i) },
|
45
|
+
resolve_idx.map { |i| @queries.at(i) }, **@kwargs
|
45
46
|
)
|
46
47
|
resolve_idx.each_with_index { |res_i, mult_i| results[res_i] = multiplex_result[mult_i] }
|
47
48
|
end
|
@@ -4,54 +4,32 @@ module GraphQL
|
|
4
4
|
module PersistedQueries
|
5
5
|
# Fetches or stores query string in the storage
|
6
6
|
class Resolver
|
7
|
-
|
8
|
-
class NotFound < StandardError
|
9
|
-
def message
|
10
|
-
"PersistedQueryNotFound"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
# Raised when provided hash is not matched with query
|
15
|
-
class WrongHash < StandardError
|
16
|
-
def message
|
17
|
-
"Wrong hash was passed"
|
18
|
-
end
|
19
|
-
end
|
7
|
+
include GraphQL::PersistedQueries::ResolverHelpers
|
20
8
|
|
21
9
|
def initialize(extensions, schema)
|
22
10
|
@extensions = extensions
|
23
11
|
@schema = schema
|
24
12
|
end
|
25
13
|
|
26
|
-
def resolve(
|
27
|
-
return
|
14
|
+
def resolve(query_string)
|
15
|
+
return query_string if hash.nil?
|
28
16
|
|
29
|
-
if
|
30
|
-
persist_query(
|
17
|
+
if query_string
|
18
|
+
persist_query(query_string)
|
31
19
|
else
|
32
|
-
|
33
|
-
raise NotFound if
|
20
|
+
query_string = with_error_handling { @schema.persisted_query_store.fetch_query(hash) }
|
21
|
+
raise GraphQL::PersistedQueries::NotFound if query_string.nil?
|
34
22
|
end
|
35
23
|
|
36
|
-
|
24
|
+
query_string
|
37
25
|
end
|
38
26
|
|
39
27
|
private
|
40
28
|
|
41
|
-
def
|
42
|
-
|
43
|
-
rescue StandardError => e
|
44
|
-
@schema.persisted_query_error_handler.call(e)
|
45
|
-
end
|
46
|
-
|
47
|
-
def persist_query(query_str)
|
48
|
-
raise WrongHash if @schema.hash_generator_proc.call(query_str) != hash
|
49
|
-
|
50
|
-
with_error_handling { @schema.persisted_query_store.save_query(hash, query_str) }
|
51
|
-
end
|
29
|
+
def persist_query(query_string)
|
30
|
+
validate_hash!(query_string)
|
52
31
|
|
53
|
-
|
54
|
-
@hash ||= @extensions.dig("persistedQuery", "sha256Hash")
|
32
|
+
with_error_handling { @schema.persisted_query_store.save_query(hash, query_string) }
|
55
33
|
end
|
56
34
|
end
|
57
35
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module PersistedQueries
|
5
|
+
# Helper functions for resolvers
|
6
|
+
module ResolverHelpers
|
7
|
+
module_function
|
8
|
+
|
9
|
+
def with_error_handling
|
10
|
+
yield
|
11
|
+
rescue StandardError => e
|
12
|
+
@schema.persisted_query_error_handler.call(e)
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate_hash!(query_string)
|
16
|
+
return if @schema.hash_generator_proc.call(query_string) == hash
|
17
|
+
|
18
|
+
raise GraphQL::PersistedQueries::WrongHash
|
19
|
+
end
|
20
|
+
|
21
|
+
def hash
|
22
|
+
@hash ||= @extensions.dig("persistedQuery", "sha256Hash")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -10,21 +10,39 @@ module GraphQL
|
|
10
10
|
# Patches GraphQL::Schema to support persisted queries
|
11
11
|
module SchemaPatch
|
12
12
|
class << self
|
13
|
-
def patch(schema)
|
14
|
-
schema.singleton_class.class_eval { alias_method :multiplex_original, :multiplex }
|
13
|
+
def patch(schema, compiled_queries)
|
15
14
|
schema.singleton_class.prepend(SchemaPatch)
|
15
|
+
|
16
|
+
return if compiled_queries
|
17
|
+
|
18
|
+
schema.singleton_class.class_eval { alias_method :multiplex_original, :multiplex }
|
19
|
+
schema.singleton_class.prepend(MultiplexPatch)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Patches GraphQL::Schema to override multiplex (not needed for compiled queries)
|
24
|
+
module MultiplexPatch
|
25
|
+
def multiplex(queries, **kwargs)
|
26
|
+
MultiplexResolver.new(self, queries, **kwargs).resolve
|
16
27
|
end
|
17
28
|
end
|
18
29
|
|
19
|
-
attr_reader :persisted_query_store, :hash_generator_proc, :persisted_query_error_handler
|
20
30
|
attr_writer :persisted_queries_tracing_enabled
|
21
31
|
|
22
|
-
def configure_persisted_query_store(store, options)
|
23
|
-
@persisted_query_store = StoreAdapters.build(store, options).tap do |adapter|
|
32
|
+
def configure_persisted_query_store(store, **options)
|
33
|
+
@persisted_query_store = StoreAdapters.build(store, **options).tap do |adapter|
|
24
34
|
adapter.tracers = tracers if persisted_queries_tracing_enabled?
|
25
35
|
end
|
26
36
|
end
|
27
37
|
|
38
|
+
def persisted_query_store
|
39
|
+
@persisted_query_store ||= find_inherited_value(:persisted_query_store)
|
40
|
+
end
|
41
|
+
|
42
|
+
def persisted_query_error_handler
|
43
|
+
@persisted_query_error_handler ||= find_inherited_value(:persisted_query_error_handler)
|
44
|
+
end
|
45
|
+
|
28
46
|
def configure_persisted_query_error_handler(handler)
|
29
47
|
@persisted_query_error_handler = ErrorHandlers.build(handler)
|
30
48
|
end
|
@@ -33,22 +51,17 @@ module GraphQL
|
|
33
51
|
@hash_generator_proc = HashGeneratorBuilder.new(hash_generator).build
|
34
52
|
end
|
35
53
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
if graphql10?
|
40
|
-
query_analyzer(prepare_analyzer)
|
41
|
-
else
|
42
|
-
query_analyzers << prepare_analyzer
|
43
|
-
end
|
54
|
+
def hash_generator_proc
|
55
|
+
@hash_generator_proc ||= find_inherited_value(:hash_generator_proc)
|
44
56
|
end
|
45
57
|
|
46
|
-
def
|
47
|
-
|
58
|
+
def verify_http_method=(verify)
|
59
|
+
query_analyzer(prepare_analyzer) if verify
|
48
60
|
end
|
49
61
|
|
50
|
-
def
|
51
|
-
|
62
|
+
def persisted_queries_tracing_enabled?
|
63
|
+
@persisted_queries_tracing_enabled ||=
|
64
|
+
find_inherited_value(:persisted_queries_tracing_enabled?)
|
52
65
|
end
|
53
66
|
|
54
67
|
def tracer(name)
|
@@ -62,12 +75,8 @@ module GraphQL
|
|
62
75
|
|
63
76
|
private
|
64
77
|
|
65
|
-
def graphql10?
|
66
|
-
Gem::Dependency.new("graphql", ">= 1.10.0").match?("graphql", GraphQL::VERSION)
|
67
|
-
end
|
68
|
-
|
69
78
|
def prepare_analyzer
|
70
|
-
if
|
79
|
+
if using_ast_analysis?
|
71
80
|
require "graphql/persisted_queries/analyzers/http_method_ast_analyzer"
|
72
81
|
Analyzers::HttpMethodAstAnalyzer
|
73
82
|
else
|
@@ -10,16 +10,16 @@ module GraphQL
|
|
10
10
|
module PersistedQueries
|
11
11
|
# Contains factory methods for store adapters
|
12
12
|
module StoreAdapters
|
13
|
-
def self.build(adapter, options
|
13
|
+
def self.build(adapter, **options)
|
14
14
|
if adapter.is_a?(StoreAdapters::BaseStoreAdapter)
|
15
15
|
adapter
|
16
16
|
else
|
17
|
-
build_by_name(adapter, options)
|
17
|
+
build_by_name(adapter, **options)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
def self.build_by_name(name, options)
|
22
|
-
const_get("#{BuilderHelpers.camelize(name)}StoreAdapter").new(options
|
21
|
+
def self.build_by_name(name, **options)
|
22
|
+
const_get("#{BuilderHelpers.camelize(name)}StoreAdapter").new(**options)
|
23
23
|
rescue NameError => e
|
24
24
|
raise e.class, "Persisted query store adapter for :#{name} haven't been found", e.backtrace
|
25
25
|
end
|
@@ -8,19 +8,22 @@ module GraphQL
|
|
8
8
|
include GraphQL::Tracing::Traceable
|
9
9
|
attr_writer :tracers
|
10
10
|
|
11
|
-
def initialize(_options)
|
11
|
+
def initialize(**_options)
|
12
12
|
@name = :base
|
13
13
|
end
|
14
14
|
|
15
|
-
def fetch_query(hash)
|
16
|
-
|
15
|
+
def fetch_query(hash, compiled_query: false)
|
16
|
+
key = build_key(hash, compiled_query)
|
17
|
+
|
18
|
+
fetch(key).tap do |result|
|
17
19
|
event = result ? "cache_hit" : "cache_miss"
|
18
20
|
trace("fetch_query.#{event}", adapter: @name)
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
22
|
-
def save_query(hash, query)
|
23
|
-
|
24
|
+
def save_query(hash, query, compiled_query: false)
|
25
|
+
key = build_key(hash, compiled_query)
|
26
|
+
trace("save_query", adapter: @name) { save(key, query) }
|
24
27
|
end
|
25
28
|
|
26
29
|
protected
|
@@ -41,6 +44,13 @@ module GraphQL
|
|
41
44
|
yield
|
42
45
|
end
|
43
46
|
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def build_key(hash, compiled_query)
|
51
|
+
key = "#{RUBY_ENGINE}-#{RUBY_VERSION}:#{GraphQL::VERSION}:#{hash}"
|
52
|
+
compiled_query ? "compiled:#{key}" : key
|
53
|
+
end
|
44
54
|
end
|
45
55
|
end
|
46
56
|
end
|
@@ -35,7 +35,7 @@ module GraphQL
|
|
35
35
|
|
36
36
|
def build_dalli_proc(dalli_client)
|
37
37
|
if dalli_client.is_a?(Hash)
|
38
|
-
build_dalli_proc(MemcachedClientBuilder.new(dalli_client).build)
|
38
|
+
build_dalli_proc(MemcachedClientBuilder.new(**dalli_client).build)
|
39
39
|
elsif dalli_client.is_a?(Proc)
|
40
40
|
dalli_client
|
41
41
|
elsif defined?(::Dalli::Client) && dalli_client.is_a?(::Dalli::Client)
|
@@ -38,7 +38,7 @@ module GraphQL
|
|
38
38
|
# rubocop: disable Metrics/PerceivedComplexity
|
39
39
|
def build_redis_proc(redis_client)
|
40
40
|
if redis_client.is_a?(Hash)
|
41
|
-
build_redis_proc(RedisClientBuilder.new(redis_client).build)
|
41
|
+
build_redis_proc(RedisClientBuilder.new(**redis_client).build)
|
42
42
|
elsif redis_client.is_a?(Proc)
|
43
43
|
redis_client
|
44
44
|
elsif defined?(::Redis) && redis_client.is_a?(::Redis)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql-persisted_queries
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- DmitryTsepelev
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.10'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.10'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -115,24 +115,31 @@ executables: []
|
|
115
115
|
extensions: []
|
116
116
|
extra_rdoc_files: []
|
117
117
|
files:
|
118
|
+
- ".github/workflows/rspec.yml"
|
119
|
+
- ".github/workflows/rubocop.yml"
|
118
120
|
- ".gitignore"
|
119
121
|
- ".rubocop.yml"
|
120
|
-
- ".travis.yml"
|
121
122
|
- CHANGELOG.md
|
122
123
|
- Gemfile
|
123
124
|
- LICENSE.txt
|
124
125
|
- README.md
|
125
126
|
- Rakefile
|
127
|
+
- benchmark/compiled_queries.rb
|
128
|
+
- benchmark/helpers.rb
|
129
|
+
- benchmark/persisted_queries.rb
|
130
|
+
- benchmark/plain_gql.rb
|
126
131
|
- bin/console
|
127
132
|
- bin/setup
|
128
133
|
- docs/alternative_stores.md
|
134
|
+
- docs/compiled_queries_benchmark.md
|
129
135
|
- docs/error_handling.md
|
130
136
|
- docs/hash.md
|
131
137
|
- docs/http_cache.md
|
132
138
|
- docs/tracing.md
|
133
139
|
- gemfiles/graphql_1_10.gemfile
|
134
|
-
- gemfiles/
|
135
|
-
- gemfiles/
|
140
|
+
- gemfiles/graphql_1_11.gemfile
|
141
|
+
- gemfiles/graphql_1_12_0.gemfile
|
142
|
+
- gemfiles/graphql_1_12_4.gemfile
|
136
143
|
- gemfiles/graphql_master.gemfile
|
137
144
|
- graphql-persisted_queries.gemspec
|
138
145
|
- lib/graphql/persisted_queries.rb
|
@@ -140,12 +147,17 @@ files:
|
|
140
147
|
- lib/graphql/persisted_queries/analyzers/http_method_ast_analyzer.rb
|
141
148
|
- lib/graphql/persisted_queries/analyzers/http_method_validator.rb
|
142
149
|
- lib/graphql/persisted_queries/builder_helpers.rb
|
150
|
+
- lib/graphql/persisted_queries/compiled_queries/multiplex_patch.rb
|
151
|
+
- lib/graphql/persisted_queries/compiled_queries/query_patch.rb
|
152
|
+
- lib/graphql/persisted_queries/compiled_queries/resolver.rb
|
143
153
|
- lib/graphql/persisted_queries/error_handlers.rb
|
144
154
|
- lib/graphql/persisted_queries/error_handlers/base_error_handler.rb
|
145
155
|
- lib/graphql/persisted_queries/error_handlers/default_error_handler.rb
|
156
|
+
- lib/graphql/persisted_queries/errors.rb
|
146
157
|
- lib/graphql/persisted_queries/hash_generator_builder.rb
|
147
158
|
- lib/graphql/persisted_queries/multiplex_resolver.rb
|
148
159
|
- lib/graphql/persisted_queries/resolver.rb
|
160
|
+
- lib/graphql/persisted_queries/resolver_helpers.rb
|
149
161
|
- lib/graphql/persisted_queries/schema_patch.rb
|
150
162
|
- lib/graphql/persisted_queries/store_adapters.rb
|
151
163
|
- lib/graphql/persisted_queries/store_adapters/base_store_adapter.rb
|
@@ -160,7 +172,7 @@ homepage: https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries
|
|
160
172
|
licenses:
|
161
173
|
- MIT
|
162
174
|
metadata: {}
|
163
|
-
post_install_message:
|
175
|
+
post_install_message:
|
164
176
|
rdoc_options: []
|
165
177
|
require_paths:
|
166
178
|
- lib
|
@@ -175,8 +187,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
175
187
|
- !ruby/object:Gem::Version
|
176
188
|
version: '0'
|
177
189
|
requirements: []
|
178
|
-
rubygems_version: 3.
|
179
|
-
signing_key:
|
190
|
+
rubygems_version: 3.1.2
|
191
|
+
signing_key:
|
180
192
|
specification_version: 4
|
181
193
|
summary: Persisted queries for graphql-ruby
|
182
194
|
test_files: []
|
data/.travis.yml
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
cache: bundler
|
3
|
-
|
4
|
-
rvm:
|
5
|
-
- 2.3
|
6
|
-
- 2.4
|
7
|
-
- 2.5
|
8
|
-
- 2.6
|
9
|
-
- ruby-head
|
10
|
-
|
11
|
-
gemfile:
|
12
|
-
- gemfiles/graphql_1_8.gemfile
|
13
|
-
- gemfiles/graphql_1_9.gemfile
|
14
|
-
- gemfiles/graphql_1_10.gemfile
|
15
|
-
- gemfiles/graphql_master.gemfile
|
16
|
-
|
17
|
-
|
18
|
-
notifications:
|
19
|
-
email: false
|
20
|
-
|
21
|
-
matrix:
|
22
|
-
fast_finish: true
|
23
|
-
allow_failures:
|
24
|
-
- rvm: ruby-head
|