graphql-persisted_queries 1.8.2 → 2.0.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/.rubocop.yml +10 -1
- data/.rubocop_todo.yml +17 -0
- data/CHANGELOG.md +6 -0
- data/README.md +2 -0
- data/benchmark/compiled_queries.rb +12 -1
- data/graphql-persisted_queries.gemspec +2 -1
- data/lib/graphql/persisted_queries/compiled_queries/instrumentation.rb +1 -1
- data/lib/graphql/persisted_queries/compiled_queries/query_patch.rb +2 -0
- data/lib/graphql/persisted_queries/compiled_queries/resolver.rb +2 -3
- data/lib/graphql/persisted_queries/store_adapters/base_store_adapter.rb +11 -1
- data/lib/graphql/persisted_queries/store_adapters/memcached_store_adapter.rb +2 -2
- data/lib/graphql/persisted_queries/store_adapters/memory_store_adapter.rb +22 -3
- data/lib/graphql/persisted_queries/store_adapters/redis_store_adapter.rb +4 -6
- data/lib/graphql/persisted_queries/store_adapters/redis_with_local_cache_store_adapter.rb +7 -2
- data/lib/graphql/persisted_queries/version.rb +1 -1
- data/lib/graphql/persisted_queries.rb +2 -2
- metadata +21 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eef23367af0ca5ac44fc10cbdd454f693c98e7e8783f0571f43a261a0e06c93f
|
4
|
+
data.tar.gz: 5338fcbb68762525ca474d4720c4f785e5f6d521d5b28bc524a187ed40553313
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8a78da34ce4706d08de137178f3f81426b590ee13568f4b7c3a8f8c6d788caf7c77a32b7ea5d12bb0ca0c139077d7a42a1192f5a4f4c07867e3634341314e7f
|
7
|
+
data.tar.gz: b02bafae180e3996349bc259d464b40d30e2ef02f078d39fb3bf4cd445cdee5152fa7c80910ba326128f4bc9d40a242895fd611c6b186eba516920bb31cf5344
|
data/.rubocop.yml
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
2
|
+
|
1
3
|
AllCops:
|
2
4
|
TargetRubyVersion: 2.6
|
3
5
|
Include:
|
@@ -15,7 +17,7 @@ AllCops:
|
|
15
17
|
Style/StringLiterals:
|
16
18
|
EnforcedStyle: double_quotes
|
17
19
|
|
18
|
-
|
20
|
+
Layout/LineLength:
|
19
21
|
Max: 100
|
20
22
|
|
21
23
|
Metrics/BlockLength:
|
@@ -24,3 +26,10 @@ Metrics/BlockLength:
|
|
24
26
|
|
25
27
|
Style/NumericLiterals:
|
26
28
|
Enabled: false
|
29
|
+
|
30
|
+
Naming/VariableNumber:
|
31
|
+
Enabled: false
|
32
|
+
|
33
|
+
Lint/ConstantDefinitionInBlock:
|
34
|
+
Exclude:
|
35
|
+
- spec/**/*
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2025-06-23 08:24:05 UTC using RuboCop version 1.77.0.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 5
|
10
|
+
# Configuration parameters: AllowedParentClasses.
|
11
|
+
Lint/MissingSuper:
|
12
|
+
Exclude:
|
13
|
+
- 'lib/graphql/persisted_queries/store_adapters/memcached_store_adapter.rb'
|
14
|
+
- 'lib/graphql/persisted_queries/store_adapters/memory_store_adapter.rb'
|
15
|
+
- 'lib/graphql/persisted_queries/store_adapters/redis_store_adapter.rb'
|
16
|
+
- 'lib/graphql/persisted_queries/store_adapters/redis_with_local_cache_store_adapter.rb'
|
17
|
+
- 'spec/graphql/persisted_queries/store_adapters/base_store_adapter_spec.rb'
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## 2.0.0 (2025-06-28)
|
4
|
+
|
5
|
+
- [PR#87](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/87)
|
6
|
+
[[BREAKING](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/87#issuecomment-3008620281)] Add option to skip query marshalling for in-memory storage ([@viralpraxis][])
|
7
|
+
|
3
8
|
## 1.8.2 (2025-06-12)
|
4
9
|
|
5
10
|
- [PR#79](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/79)
|
@@ -134,3 +139,4 @@ Handle situations when prepare_ast happens before instrumentation ([@DmitryTsepe
|
|
134
139
|
[@rbviz]: https://github.com/rbviz
|
135
140
|
[@louim]: https://github.com/louim
|
136
141
|
[@mpospelov]: https://github.com/mpospelov
|
142
|
+
[@viralpraxis]: https://github.com/viralpraxis
|
data/README.md
CHANGED
@@ -92,6 +92,8 @@ It is possible to skip some parts of the query lifecycle for cases when query is
|
|
92
92
|
|
93
93
|
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).
|
94
94
|
|
95
|
+
You can skip marshalling for queries stored in memory by passing the `marshal_inmemory_queries: false` option. This only affects the `memory` and `redis_with_local_cache` stores.
|
96
|
+
|
95
97
|
> 📖 Read more about the gem internals: [Persisted queries in GraphQL:
|
96
98
|
Slim down Apollo requests to your Ruby application](https://evilmartians.com/chronicles/persisted-queries-in-graphql-slim-down-apollo-requests-to-your-ruby-application)
|
97
99
|
|
@@ -17,6 +17,12 @@ class GraphqlSchema < GraphQL::Schema
|
|
17
17
|
query QueryType
|
18
18
|
end
|
19
19
|
|
20
|
+
class GraphqlSchemaWithoutMarshalling < GraphQL::Schema
|
21
|
+
use GraphQL::PersistedQueries, compiled_queries: true, marshal_inmemory_queries: false
|
22
|
+
|
23
|
+
query QueryType
|
24
|
+
end
|
25
|
+
|
20
26
|
GraphqlSchema.to_definition
|
21
27
|
|
22
28
|
puts
|
@@ -32,10 +38,15 @@ Benchmark.bm(28) do |x|
|
|
32
38
|
context = { extensions: { "persistedQuery" => { "sha256Hash" => sha256 } } }
|
33
39
|
# warmup
|
34
40
|
GraphqlSchema.execute(query, context: context)
|
41
|
+
GraphqlSchemaWithoutMarshalling.execute(query, context: context)
|
35
42
|
|
36
|
-
x.report("#{field_count} fields#{
|
43
|
+
x.report("#{field_count} fields#{' (nested)' if with_nested} (marshalled)") do
|
37
44
|
GraphqlSchema.execute(query, context: context)
|
38
45
|
end
|
46
|
+
|
47
|
+
x.report("#{field_count} fields#{' (nested)' if with_nested}") do
|
48
|
+
GraphqlSchemaWithoutMarshalling.execute(query, context: context)
|
49
|
+
end
|
39
50
|
end
|
40
51
|
end
|
41
52
|
end
|
@@ -27,8 +27,9 @@ Gem::Specification.new do |spec|
|
|
27
27
|
|
28
28
|
spec.add_development_dependency "rspec", "~> 3.9"
|
29
29
|
spec.add_development_dependency "rake", ">= 10.0"
|
30
|
-
spec.add_development_dependency "rubocop", "0
|
30
|
+
spec.add_development_dependency "rubocop", "~> 1.77.0"
|
31
31
|
spec.add_development_dependency "redis"
|
32
32
|
spec.add_development_dependency "dalli"
|
33
33
|
spec.add_development_dependency "connection_pool"
|
34
|
+
spec.add_development_dependency "benchmark"
|
34
35
|
end
|
@@ -8,7 +8,7 @@ module GraphQL
|
|
8
8
|
class << self
|
9
9
|
# Actions to perform before the query resolution
|
10
10
|
def before_query(query)
|
11
|
-
query = query.query if query.class.name == "GraphQL::Query::Partial"
|
11
|
+
query = query.query if query.class.name == "GraphQL::Query::Partial" # rubocop:disable Style/ClassEqualityComparison
|
12
12
|
|
13
13
|
return unless query.context[:extensions]
|
14
14
|
|
@@ -13,6 +13,7 @@ module GraphQL
|
|
13
13
|
@persisted_query_not_found
|
14
14
|
end
|
15
15
|
|
16
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
16
17
|
def prepare_ast
|
17
18
|
return super if @context[:extensions].nil? || @document
|
18
19
|
|
@@ -27,6 +28,7 @@ module GraphQL
|
|
27
28
|
resolver.persist(query_string, @document)
|
28
29
|
end
|
29
30
|
end
|
31
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
30
32
|
end
|
31
33
|
|
32
34
|
def try_load_document!
|
@@ -38,8 +38,7 @@ module GraphQL
|
|
38
38
|
return if hash.nil?
|
39
39
|
|
40
40
|
with_error_handling do
|
41
|
-
|
42
|
-
Marshal.load(compiled_query) if compiled_query # rubocop:disable Security/MarshalLoad
|
41
|
+
@schema.persisted_query_store.fetch_query(hash, compiled_query: true)
|
43
42
|
end
|
44
43
|
end
|
45
44
|
|
@@ -50,7 +49,7 @@ module GraphQL
|
|
50
49
|
|
51
50
|
with_error_handling do
|
52
51
|
@schema.persisted_query_store.save_query(
|
53
|
-
hash,
|
52
|
+
hash, compiled_query, compiled_query: true
|
54
53
|
)
|
55
54
|
end
|
56
55
|
end
|
@@ -24,7 +24,9 @@ module GraphQL
|
|
24
24
|
|
25
25
|
def save_query(hash, query, compiled_query: false)
|
26
26
|
key = build_key(hash, compiled_query)
|
27
|
-
trace("save_query", adapter: @name)
|
27
|
+
trace("save_query", adapter: @name) do
|
28
|
+
query.tap { save(key, query) }
|
29
|
+
end
|
28
30
|
end
|
29
31
|
|
30
32
|
def fetch(_hash)
|
@@ -44,6 +46,14 @@ module GraphQL
|
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
49
|
+
def serialize(query)
|
50
|
+
Marshal.dump(query)
|
51
|
+
end
|
52
|
+
|
53
|
+
def deserialize(serialized_query)
|
54
|
+
Marshal.load(serialized_query) if serialized_query # rubocop:disable Security/MarshalLoad
|
55
|
+
end
|
56
|
+
|
47
57
|
private
|
48
58
|
|
49
59
|
def build_key(hash, compiled_query)
|
@@ -18,11 +18,11 @@ module GraphQL
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def fetch(hash)
|
21
|
-
@dalli_proc.call { |dalli| dalli.get(key_for(hash)) }
|
21
|
+
@dalli_proc.call { |dalli| deserialize(dalli.get(key_for(hash))) }
|
22
22
|
end
|
23
23
|
|
24
24
|
def save(hash, query)
|
25
|
-
@dalli_proc.call { |dalli| dalli.set(key_for(hash), query, @expiration) }
|
25
|
+
@dalli_proc.call { |dalli| dalli.set(key_for(hash), serialize(query), @expiration) }
|
26
26
|
end
|
27
27
|
|
28
28
|
private
|
@@ -5,17 +5,36 @@ module GraphQL
|
|
5
5
|
module StoreAdapters
|
6
6
|
# Memory adapter for storing persisted queries
|
7
7
|
class MemoryStoreAdapter < BaseStoreAdapter
|
8
|
-
def initialize(**
|
8
|
+
def initialize(**options)
|
9
9
|
@storage = {}
|
10
10
|
@name = :memory
|
11
|
+
@marshal_inmemory_queries = options.fetch(:marshal_inmemory_queries, true)
|
11
12
|
end
|
12
13
|
|
13
14
|
def fetch(hash)
|
14
|
-
@storage[hash]
|
15
|
+
deserialize(@storage[hash])
|
15
16
|
end
|
16
17
|
|
17
18
|
def save(hash, query)
|
18
|
-
@storage[hash] = query
|
19
|
+
@storage[hash] = serialize(query)
|
20
|
+
end
|
21
|
+
|
22
|
+
def serialize(query)
|
23
|
+
if @marshal_inmemory_queries
|
24
|
+
super(query)
|
25
|
+
else
|
26
|
+
query
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def deserialize(serialized_query)
|
31
|
+
return unless serialized_query
|
32
|
+
|
33
|
+
if @marshal_inmemory_queries
|
34
|
+
super(serialized_query)
|
35
|
+
else
|
36
|
+
serialized_query
|
37
|
+
end
|
19
38
|
end
|
20
39
|
end
|
21
40
|
end
|
@@ -18,11 +18,13 @@ module GraphQL
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def fetch(hash)
|
21
|
-
@redis_proc.call
|
21
|
+
@redis_proc.call do |redis|
|
22
|
+
deserialize(redis.get(key_for(hash)))
|
23
|
+
end
|
22
24
|
end
|
23
25
|
|
24
26
|
def save(hash, query)
|
25
|
-
@redis_proc.call { |redis| redis.set(key_for(hash), query, ex: @expiration) }
|
27
|
+
@redis_proc.call { |redis| redis.set(key_for(hash), serialize(query), ex: @expiration) }
|
26
28
|
end
|
27
29
|
|
28
30
|
private
|
@@ -32,8 +34,6 @@ module GraphQL
|
|
32
34
|
end
|
33
35
|
|
34
36
|
# rubocop: disable Metrics/MethodLength
|
35
|
-
# rubocop: disable Metrics/CyclomaticComplexity
|
36
|
-
# rubocop: disable Metrics/PerceivedComplexity
|
37
37
|
def build_redis_proc(redis_client)
|
38
38
|
if redis_client.is_a?(Hash)
|
39
39
|
build_redis_proc(RedisClientBuilder.new(**redis_client).build)
|
@@ -48,8 +48,6 @@ module GraphQL
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
# rubocop: enable Metrics/MethodLength
|
51
|
-
# rubocop: enable Metrics/CyclomaticComplexity
|
52
|
-
# rubocop: enable Metrics/PerceivedComplexity
|
53
51
|
end
|
54
52
|
end
|
55
53
|
end
|
@@ -8,8 +8,9 @@ module GraphQL
|
|
8
8
|
DEFAULT_REDIS_ADAPTER_CLASS = RedisStoreAdapter
|
9
9
|
DEFAULT_MEMORY_ADAPTER_CLASS = MemoryStoreAdapter
|
10
10
|
|
11
|
+
# rubocop:disable Metrics/ParameterLists, Metrics/MethodLength
|
11
12
|
def initialize(redis_client: {}, expiration: nil, namespace: nil, redis_adapter_class: nil,
|
12
|
-
memory_adapter_class: nil)
|
13
|
+
memory_adapter_class: nil, marshal_inmemory_queries: true)
|
13
14
|
redis_adapter_class ||= DEFAULT_REDIS_ADAPTER_CLASS
|
14
15
|
memory_adapter_class ||= DEFAULT_MEMORY_ADAPTER_CLASS
|
15
16
|
|
@@ -18,9 +19,13 @@ module GraphQL
|
|
18
19
|
expiration: expiration,
|
19
20
|
namespace: namespace
|
20
21
|
)
|
21
|
-
@
|
22
|
+
@marshal_inmemory_queries = marshal_inmemory_queries
|
23
|
+
@memory_adapter = memory_adapter_class.new(
|
24
|
+
marshal_inmemory_queries: marshal_inmemory_queries
|
25
|
+
)
|
22
26
|
@name = :redis_with_local_cache
|
23
27
|
end
|
28
|
+
# rubocop:enable Metrics/ParameterLists, Metrics/MethodLength
|
24
29
|
|
25
30
|
def fetch(hash)
|
26
31
|
result = @memory_adapter.fetch(hash)
|
@@ -15,7 +15,7 @@ require "graphql/persisted_queries/compiled_queries/query_patch"
|
|
15
15
|
module GraphQL
|
16
16
|
# Plugin definition
|
17
17
|
module PersistedQueries
|
18
|
-
# rubocop:disable Metrics/MethodLength
|
18
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
19
19
|
def self.use(schema_defn, **options)
|
20
20
|
schema = schema_defn.is_a?(Class) ? schema_defn : schema_defn.target
|
21
21
|
|
@@ -35,7 +35,7 @@ module GraphQL
|
|
35
35
|
store = options.delete(:store) || :memory
|
36
36
|
schema.configure_persisted_query_store(store, **options)
|
37
37
|
end
|
38
|
-
# rubocop:enable Metrics/MethodLength
|
38
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
39
39
|
|
40
40
|
def self.configure_compiled_queries
|
41
41
|
if Gem::Dependency.new("graphql", "< 1.12.0").match?("graphql", GraphQL::VERSION)
|
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:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- DmitryTsepelev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-06-
|
11
|
+
date: 2025-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -70,16 +70,16 @@ dependencies:
|
|
70
70
|
name: rubocop
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 1.77.0
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 1.77.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: redis
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: benchmark
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
125
139
|
description: Persisted queries for graphql-ruby
|
126
140
|
email:
|
127
141
|
- dmitry.a.tsepelev@gmail.com
|
@@ -133,6 +147,7 @@ files:
|
|
133
147
|
- ".github/workflows/rubocop.yml"
|
134
148
|
- ".gitignore"
|
135
149
|
- ".rubocop.yml"
|
150
|
+
- ".rubocop_todo.yml"
|
136
151
|
- CHANGELOG.md
|
137
152
|
- Gemfile
|
138
153
|
- LICENSE.txt
|