graphql-persisted_queries 1.1.0 → 1.2.3
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 +4 -3
- data/CHANGELOG.md +23 -0
- data/README.md +24 -12
- 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/alternative_stores.md +3 -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 +3 -3
- 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/store_adapters/redis_with_local_cache_store_adapter.rb +1 -1
- data/lib/graphql/persisted_queries/version.rb +1 -1
- metadata +21 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49c69f6c97fdc5fa85c34915dc2f214fc38d5cbc0c22051cac9c3c2eecce27e3
|
4
|
+
data.tar.gz: c0579d6c06361875fe255c96eae906a9317a6f993fbefd637ac181c2dc985fac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61a3c88f6f03ccfd956d50ccd49dca4a9f2b51f13fb45672f226b8b112401944f14f974f692a3dd60b120d9bc6903efe017b9f5be62ec9f0a5d17919f0f881d9
|
7
|
+
data.tar.gz: 5b9f8cac85ee76c5091e3d6ae87c58ee45cc1048831c480b2a06edc84a26aa8432030da2318a50c0b72f630fa12db6c05a16751121e1f741d1ed9b44b25d4297
|
data/.github/workflows/rspec.yml
CHANGED
@@ -20,9 +20,10 @@ jobs:
|
|
20
20
|
matrix:
|
21
21
|
ruby: [2.3, 2.4, 2.5, 2.6, 2.7]
|
22
22
|
gemfile: [
|
23
|
-
"gemfiles/graphql_1_8.gemfile",
|
24
|
-
"gemfiles/graphql_1_9.gemfile",
|
25
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",
|
26
27
|
"gemfiles/graphql_master.gemfile"
|
27
28
|
]
|
28
29
|
|
@@ -49,4 +50,4 @@ jobs:
|
|
49
50
|
bundle update
|
50
51
|
- name: Run RSpec
|
51
52
|
run: |
|
52
|
-
bundle exec rake
|
53
|
+
bundle exec rake ci_specs
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,27 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 1.2.3 (2021-05-14)
|
6
|
+
|
7
|
+
- [PR#49](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/49) Allow nil redis_client with ENV["REDIS_URL"] ([@louim][])
|
8
|
+
|
9
|
+
## 1.2.2 (2021-04-21)
|
10
|
+
|
11
|
+
- [PR#47](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/47) Properly initialize memory adapter inside RedisWithLocalCacheStoreAdapter ([@DmitryTsepelev][])
|
12
|
+
|
13
|
+
## 1.2.1 (2021-03-07)
|
14
|
+
|
15
|
+
- [PR#43](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/43) Properly handle configuration when schema is inherited ([@DmitryTsepelev][])
|
16
|
+
- [PR#44](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/44) Deprecate graphql-ruby 1.8 and 1.9 ([@DmitryTsepelev][])
|
17
|
+
|
18
|
+
## 1.2.0 (2021-02-24)
|
19
|
+
|
20
|
+
- [PR#39](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/39) Implement compiled queries ([@DmitryTsepelev][])
|
21
|
+
|
22
|
+
## 1.1.1 (2020-12-03)
|
23
|
+
|
24
|
+
- [PR#37](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/37) Fix deprecation warnings ([@rbviz][])
|
25
|
+
|
5
26
|
## 1.1.0 (2020-11-16)
|
6
27
|
|
7
28
|
- [PR#36](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/36) Support Ruby 2.7.0 ([@DmitryTsepelev][])
|
@@ -60,3 +81,5 @@
|
|
60
81
|
[@bmorton]: https://github.com/bmorton
|
61
82
|
[@JanStevens]: https://github.com/JanStevens
|
62
83
|
[@ogidow]: https://github.com/ogidow
|
84
|
+
[@rbviz]: https://github.com/rbviz
|
85
|
+
[@louim]: https://github.com/louim
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# GraphQL::PersistedQueries
|
2
2
|
|
3
|
-
`GraphQL::PersistedQueries` is the implementation of [persisted queries](https://
|
3
|
+
`GraphQL::PersistedQueries` is the implementation of [persisted queries](https://www.apollographql.com/docs/react/api/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.
|
4
4
|
|
5
5
|
- 🗑**Heavy query parameter will be omitted in most of cases** – network requests will become less heavy
|
6
6
|
- 🤝**Clients share cached queries** – it's enough to miss cache only once for each unique query
|
@@ -15,20 +15,18 @@
|
|
15
15
|
|
16
16
|
## Getting started
|
17
17
|
|
18
|
-
First of all, install and configure [apollo
|
18
|
+
First of all, install and configure [apollo's persisted queries](https://www.apollographql.com/docs/react/api/link/persisted-queries/) on the front–end side:
|
19
19
|
|
20
20
|
```js
|
21
|
-
import {
|
22
|
-
import {
|
23
|
-
import {
|
24
|
-
import ApolloClient from "apollo-client";
|
21
|
+
import { HttpLink, InMemoryCache, ApolloClient } from "@apollo/client";
|
22
|
+
import { createPersistedQueryLink } from "@apollo/client/link/persisted-queries";
|
23
|
+
import { sha256 } from 'crypto-hash';
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
const link = createPersistedQueryLink().concat(createHttpLink({ uri: "/graphql" }));
|
25
|
+
const httpLink = new HttpLink({ uri: "/graphql" });
|
26
|
+
const persistedQueriesLink = createPersistedQueryLink({ sha256 });
|
29
27
|
const client = new ApolloClient({
|
30
28
|
cache: new InMemoryCache(),
|
31
|
-
link:
|
29
|
+
link: persistedQueriesLink.concat(httpLink);
|
32
30
|
});
|
33
31
|
```
|
34
32
|
|
@@ -65,6 +63,20 @@ GraphqlSchema.execute(
|
|
65
63
|
|
66
64
|
You're all set!
|
67
65
|
|
66
|
+
## Compiled queries (increases performance up to 2x!)
|
67
|
+
|
68
|
+
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:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
class GraphqlSchema < GraphQL::Schema
|
72
|
+
use GraphQL::PersistedQueries, compiled_queries: true
|
73
|
+
end
|
74
|
+
```
|
75
|
+
|
76
|
+
Using this option might make your endpoint up to 2x faster according to the [benchmark](docs/compiled_queries_benchmark.md).
|
77
|
+
|
78
|
+
**Heads up!** This feature only works on `graphql-ruby` 1.12.0 or later, but I guess it might be backported.
|
79
|
+
|
68
80
|
## Advanced usage
|
69
81
|
|
70
82
|
All the queries are stored in memory by default, but you can easily switch to another storage (e.g., _redis_:
|
@@ -81,9 +93,9 @@ When the error occurs, the gem tries to not interrupt the regular flow of the ap
|
|
81
93
|
|
82
94
|
Since our queries are slim now, we can switch back to HTTP GET, you can find a [guide](docs/http_cache.md) here.
|
83
95
|
|
84
|
-
[batch-link](https://www.apollographql.com/docs/link/
|
96
|
+
[batch-link](https://www.apollographql.com/docs/react/api/link/apollo-link-batch-http/) allows to group queries on the client side into a single HTTP request before sending to the server. In this case you need to use `GraphqlSchema.multiplex(queries)` instead of `#execute`. The gem supports it too, no action required!
|
85
97
|
|
86
|
-
[
|
98
|
+
[persisted-queries-link](https://www.apollographql.com/docs/react/api/link/persisted-queries/) uses _SHA256_ for building hashes by default. Check out this [guide](docs/hash.md) if you want to override this behavior.
|
87
99
|
|
88
100
|
An experimental tracing feature can be enabled by setting `tracing: true` when configuring the plugin. Read more about this feature in the [Tracing guide](docs/tracing.md).
|
89
101
|
|
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
|
data/docs/alternative_stores.md
CHANGED
@@ -25,6 +25,9 @@ class GraphqlSchema < GraphQL::Schema
|
|
25
25
|
use GraphQL::PersistedQueries,
|
26
26
|
store: :redis,
|
27
27
|
redis_client: ConnectionPool.new { Redis.new(url: "redis://127.0.0.2:2214/7") }
|
28
|
+
# or with ENV["REDIS_URL"]
|
29
|
+
use GraphQL::PersistedQueries,
|
30
|
+
store: :redis
|
28
31
|
end
|
29
32
|
```
|
30
33
|
|
@@ -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,7 +33,7 @@ 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
39
|
results[pos] = GraphQL::Query::Result.new(query: query, values: values)
|
@@ -42,7 +42,7 @@ module GraphQL
|
|
42
42
|
def perform_multiplex
|
43
43
|
resolve_idx = (0...@queries.count).select { |i| results[i].nil? }
|
44
44
|
multiplex_result = @schema.multiplex_original(
|
45
|
-
resolve_idx.map { |i| @queries.at(i) },
|
45
|
+
resolve_idx.map { |i| @queries.at(i) }, **@kwargs
|
46
46
|
)
|
47
47
|
resolve_idx.each_with_index { |res_i, mult_i| results[res_i] = multiplex_result[mult_i] }
|
48
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)
|
@@ -10,7 +10,7 @@ module GraphQL
|
|
10
10
|
DEFAULT_EXPIRATION = 24 * 60 * 60
|
11
11
|
DEFAULT_NAMESPACE = "graphql-persisted-query"
|
12
12
|
|
13
|
-
def initialize(redis_client
|
13
|
+
def initialize(redis_client: {}, expiration: nil, namespace: nil)
|
14
14
|
@redis_proc = build_redis_proc(redis_client)
|
15
15
|
@expiration = expiration || DEFAULT_EXPIRATION
|
16
16
|
@namespace = namespace || DEFAULT_NAMESPACE
|
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.3
|
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-05-14 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
|
@@ -124,16 +124,22 @@ files:
|
|
124
124
|
- LICENSE.txt
|
125
125
|
- README.md
|
126
126
|
- Rakefile
|
127
|
+
- benchmark/compiled_queries.rb
|
128
|
+
- benchmark/helpers.rb
|
129
|
+
- benchmark/persisted_queries.rb
|
130
|
+
- benchmark/plain_gql.rb
|
127
131
|
- bin/console
|
128
132
|
- bin/setup
|
129
133
|
- docs/alternative_stores.md
|
134
|
+
- docs/compiled_queries_benchmark.md
|
130
135
|
- docs/error_handling.md
|
131
136
|
- docs/hash.md
|
132
137
|
- docs/http_cache.md
|
133
138
|
- docs/tracing.md
|
134
139
|
- gemfiles/graphql_1_10.gemfile
|
135
|
-
- gemfiles/
|
136
|
-
- gemfiles/
|
140
|
+
- gemfiles/graphql_1_11.gemfile
|
141
|
+
- gemfiles/graphql_1_12_0.gemfile
|
142
|
+
- gemfiles/graphql_1_12_4.gemfile
|
137
143
|
- gemfiles/graphql_master.gemfile
|
138
144
|
- graphql-persisted_queries.gemspec
|
139
145
|
- lib/graphql/persisted_queries.rb
|
@@ -141,12 +147,17 @@ files:
|
|
141
147
|
- lib/graphql/persisted_queries/analyzers/http_method_ast_analyzer.rb
|
142
148
|
- lib/graphql/persisted_queries/analyzers/http_method_validator.rb
|
143
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
|
144
153
|
- lib/graphql/persisted_queries/error_handlers.rb
|
145
154
|
- lib/graphql/persisted_queries/error_handlers/base_error_handler.rb
|
146
155
|
- lib/graphql/persisted_queries/error_handlers/default_error_handler.rb
|
156
|
+
- lib/graphql/persisted_queries/errors.rb
|
147
157
|
- lib/graphql/persisted_queries/hash_generator_builder.rb
|
148
158
|
- lib/graphql/persisted_queries/multiplex_resolver.rb
|
149
159
|
- lib/graphql/persisted_queries/resolver.rb
|
160
|
+
- lib/graphql/persisted_queries/resolver_helpers.rb
|
150
161
|
- lib/graphql/persisted_queries/schema_patch.rb
|
151
162
|
- lib/graphql/persisted_queries/store_adapters.rb
|
152
163
|
- lib/graphql/persisted_queries/store_adapters/base_store_adapter.rb
|
@@ -161,7 +172,7 @@ homepage: https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries
|
|
161
172
|
licenses:
|
162
173
|
- MIT
|
163
174
|
metadata: {}
|
164
|
-
post_install_message:
|
175
|
+
post_install_message:
|
165
176
|
rdoc_options: []
|
166
177
|
require_paths:
|
167
178
|
- lib
|
@@ -176,8 +187,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
176
187
|
- !ruby/object:Gem::Version
|
177
188
|
version: '0'
|
178
189
|
requirements: []
|
179
|
-
rubygems_version: 3.
|
180
|
-
signing_key:
|
190
|
+
rubygems_version: 3.1.2
|
191
|
+
signing_key:
|
181
192
|
specification_version: 4
|
182
193
|
summary: Persisted queries for graphql-ruby
|
183
194
|
test_files: []
|