graphql-persisted_queries 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +47 -3
- data/graphql-persisted_queries.gemspec +1 -0
- data/lib/graphql/persisted_queries/store_adapters.rb +1 -0
- data/lib/graphql/persisted_queries/store_adapters/memcached_client_builder.rb +38 -0
- data/lib/graphql/persisted_queries/store_adapters/memcached_store_adapter.rb +47 -0
- data/lib/graphql/persisted_queries/version.rb +1 -1
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 12531a6f0099e3220f5ea0bf400b1ccd23f2e6f3161d91d54c05ae404d3e1532
|
4
|
+
data.tar.gz: 4660b422f801db343ce2f8e04ea21576ae500d7d9519f87399300e957f555160
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2d317723d55e67aebc607624e32e7052c53f378e8dd4584d161102167f5f44c221580518ab912a88db3e8b82381455ba77b20aefce5904602159c33bd23b88c
|
7
|
+
data.tar.gz: b831aeb69392cdd662fcf285cc8f48051feb3cd3703db862bd4434cfdbb67acd4b85cf70ae64cbcee61f7df969cbd913c152517af4a7da2b7121ae99fd0282a4
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.4.0 (2020-02-26)
|
6
|
+
|
7
|
+
- [PR#26](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/26) Add Memcached store ([@JanStevens][])
|
8
|
+
|
5
9
|
## 0.3.0 (2020-02-21)
|
6
10
|
|
7
11
|
- [PR#24](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/24) Add multiplex support ([@DmitryTsepelev][])
|
@@ -30,3 +34,4 @@
|
|
30
34
|
|
31
35
|
[@DmitryTsepelev]: https://github.com/DmitryTsepelev
|
32
36
|
[@bmorton]: https://github.com/bmorton
|
37
|
+
[@JanStevens]: https://github.com/JanStevens
|
data/README.md
CHANGED
@@ -59,11 +59,12 @@ GraphqlSchema.execute(
|
|
59
59
|
|
60
60
|
## Usage with BatchLink
|
61
61
|
|
62
|
-
It's possible to group queries using [batch-link](https://www.apollographql.com/docs/link/links/batch-http/) and send them as a single HTTP request.
|
62
|
+
It's possible to group queries using [batch-link](https://www.apollographql.com/docs/link/links/batch-http/) and send them as a single HTTP request.
|
63
|
+
In this case you need to use `GraphqlSchema.multiplex(queries)` instead of `#execute`. The gem supports it too, no action required!
|
63
64
|
|
64
65
|
## Alternative stores
|
65
66
|
|
66
|
-
All the queries are stored in memory by default, but you can easily switch to _redis_:
|
67
|
+
All the queries are stored in memory by default, but you can easily switch to _redis_ or _memcached_:
|
67
68
|
|
68
69
|
```ruby
|
69
70
|
class GraphqlSchema < GraphQL::Schema
|
@@ -71,7 +72,10 @@ class GraphqlSchema < GraphQL::Schema
|
|
71
72
|
end
|
72
73
|
```
|
73
74
|
|
74
|
-
|
75
|
+
### Redis
|
76
|
+
|
77
|
+
If you have `ENV["REDIS_URL"]` configured – you don't need to pass it explicitly. Also, you can pass `:redis_host`, `:redis_port` and `:redis_db_name`
|
78
|
+
inside the `:redis_client` hash to build the URL from scratch or pass the configured `Redis` or `ConnectionPool` object:
|
75
79
|
|
76
80
|
```ruby
|
77
81
|
class GraphqlSchema < GraphQL::Schema
|
@@ -101,6 +105,45 @@ class GraphqlSchema < GraphQL::Schema
|
|
101
105
|
end
|
102
106
|
```
|
103
107
|
|
108
|
+
### Memcached
|
109
|
+
|
110
|
+
If you have `ENV["MEMCACHE_SERVERS"]` configured - you don't need to pass it explicitly. Also, you can pass `:memcached_host` and `:memcached_port`
|
111
|
+
inside the `:dalli_client` hash to build the server name from scratch or pass the configured `Dalli::Client` object:
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
class GraphqlSchema < GraphQL::Schema
|
115
|
+
use GraphQL::PersistedQueries,
|
116
|
+
store: :memcached,
|
117
|
+
dalli_client: { memcached_host: "127.0.0.2", memcached_port: "11211" }
|
118
|
+
# or
|
119
|
+
use GraphQL::PersistedQueries,
|
120
|
+
store: :memcached,
|
121
|
+
dalli_client: Dalli::Client.new("127.0.0.2:11211")
|
122
|
+
# or
|
123
|
+
use GraphQL::PersistedQueries,
|
124
|
+
store: :memcached,
|
125
|
+
dalli_client: { memcached_url: "127.0.0.2:11211" }
|
126
|
+
end
|
127
|
+
```
|
128
|
+
|
129
|
+
You can also pass options for `expiration` and `namespace` to override the defaults.
|
130
|
+
Any additional argument inside `dalli_client` will be forwarded to `Dalli::Client.new`.
|
131
|
+
Following example configures Dalli `pool_size` and `compress` options:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
class GraphqlSchema < GraphQL::Schema
|
135
|
+
use GraphQL::PersistedQueries,
|
136
|
+
store: :memcached,
|
137
|
+
dalli_client: {
|
138
|
+
memcached_url: "127.0.0.2:11211",
|
139
|
+
pool_size: 5,
|
140
|
+
compress: true
|
141
|
+
},
|
142
|
+
expiration: 172800, # optional, default is 24 hours
|
143
|
+
namespace: "my-custom-namespace" # optional, default is "graphql-persisted-query"
|
144
|
+
end
|
145
|
+
```
|
146
|
+
|
104
147
|
### Supported stores
|
105
148
|
|
106
149
|
We currently support a few different stores that can be configured out of the box:
|
@@ -108,6 +151,7 @@ We currently support a few different stores that can be configured out of the bo
|
|
108
151
|
- `:memory`: This is the default in-memory store and is great for getting started, but will require each instance to cache results independently which can result in lots of ["new query path"](https://blog.apollographql.com/improve-graphql-performance-with-automatic-persisted-queries-c31d27b8e6ea) requests.
|
109
152
|
- `:redis`: This store will allow you to share a Redis cache across all instances of your GraphQL application so that each instance doesn't have to ask the client for the query again if it hasn't seen it yet.
|
110
153
|
- `:redis_with_local_cache`: This store combines both the `:memory` and `:redis` approaches so that we can reduce the number of network requests we make while mitigating the independent cache issue. This adapter is configured identically to the `:redis` store.
|
154
|
+
- `:memcached`: This store will allow you to share a Memcached cache across all instances of your GraphQL application. The client is implemented with the Dalli gem.
|
111
155
|
|
112
156
|
## Alternative hash functions
|
113
157
|
|
@@ -28,5 +28,6 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_development_dependency "rake", ">= 10.0"
|
29
29
|
spec.add_development_dependency "rubocop", "0.75"
|
30
30
|
spec.add_development_dependency "redis"
|
31
|
+
spec.add_development_dependency "dalli"
|
31
32
|
spec.add_development_dependency "connection_pool"
|
32
33
|
end
|
@@ -4,6 +4,7 @@ require "graphql/persisted_queries/store_adapters/base_store_adapter"
|
|
4
4
|
require "graphql/persisted_queries/store_adapters/memory_store_adapter"
|
5
5
|
require "graphql/persisted_queries/store_adapters/redis_store_adapter"
|
6
6
|
require "graphql/persisted_queries/store_adapters/redis_with_local_cache_store_adapter"
|
7
|
+
require "graphql/persisted_queries/store_adapters/memcached_store_adapter"
|
7
8
|
|
8
9
|
module GraphQL
|
9
10
|
module PersistedQueries
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module PersistedQueries
|
5
|
+
module StoreAdapters
|
6
|
+
# Builds Redis object instance based on passed hash
|
7
|
+
class MemcachedClientBuilder
|
8
|
+
def initialize(memcached_url: nil, memcached_host: nil, memcached_port: nil, **dalli_args)
|
9
|
+
require "dalli"
|
10
|
+
|
11
|
+
@memcached_url = memcached_url
|
12
|
+
@memcached_host = memcached_host
|
13
|
+
@memcached_port = memcached_port
|
14
|
+
@dalli_args = dalli_args
|
15
|
+
rescue LoadError => e
|
16
|
+
msg = "Could not load the 'dalli' gem, please add it to your gemfile or " \
|
17
|
+
"configure a different adapter, e.g. use GraphQL::PersistedQueries, store: :memory"
|
18
|
+
raise e.class, msg, e.backtrace
|
19
|
+
end
|
20
|
+
|
21
|
+
def build
|
22
|
+
if @memcached_url && (@memcached_host || @memcached_port)
|
23
|
+
raise ArgumentError, "memcached_url cannot be passed along with memcached_host or " \
|
24
|
+
"memcached_port options"
|
25
|
+
end
|
26
|
+
|
27
|
+
::Dalli::Client.new(@memcached_url || build_memcached_url, **@dalli_args)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def build_memcached_url
|
33
|
+
"#{@memcached_host}:#{@memcached_port}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "graphql/persisted_queries/store_adapters/memcached_client_builder"
|
4
|
+
|
5
|
+
module GraphQL
|
6
|
+
module PersistedQueries
|
7
|
+
module StoreAdapters
|
8
|
+
# Redis adapter for storing persisted queries
|
9
|
+
class MemcachedStoreAdapter < BaseStoreAdapter
|
10
|
+
DEFAULT_EXPIRATION = 24 * 60 * 60
|
11
|
+
DEFAULT_NAMESPACE = "graphql-persisted-query"
|
12
|
+
|
13
|
+
def initialize(dalli_client:, expiration: nil, namespace: nil)
|
14
|
+
@dalli_proc = build_dalli_proc(dalli_client)
|
15
|
+
@expiration = expiration || DEFAULT_EXPIRATION
|
16
|
+
@namespace = namespace || DEFAULT_NAMESPACE
|
17
|
+
end
|
18
|
+
|
19
|
+
def fetch_query(hash)
|
20
|
+
@dalli_proc.call { |dalli| dalli.get(key_for(hash)) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def save_query(hash, query)
|
24
|
+
@dalli_proc.call { |dalli| dalli.set(key_for(hash), query, @expiration) }
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def key_for(hash)
|
30
|
+
"#{@namespace}:#{hash}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def build_dalli_proc(dalli_client)
|
34
|
+
if dalli_client.is_a?(Hash)
|
35
|
+
build_dalli_proc(MemcachedClientBuilder.new(dalli_client).build)
|
36
|
+
elsif dalli_client.is_a?(Proc)
|
37
|
+
dalli_client
|
38
|
+
elsif defined?(::Dalli::Client) && dalli_client.is_a?(::Dalli::Client)
|
39
|
+
proc { |&b| b.call(dalli_client) }
|
40
|
+
else
|
41
|
+
raise ArgumentError, ":dalli_client accepts Dalli::Client, Hash or Proc only"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
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: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- DmitryTsepelev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-02-
|
11
|
+
date: 2020-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: dalli
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: connection_pool
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,6 +142,8 @@ files:
|
|
128
142
|
- lib/graphql/persisted_queries/schema_patch.rb
|
129
143
|
- lib/graphql/persisted_queries/store_adapters.rb
|
130
144
|
- lib/graphql/persisted_queries/store_adapters/base_store_adapter.rb
|
145
|
+
- lib/graphql/persisted_queries/store_adapters/memcached_client_builder.rb
|
146
|
+
- lib/graphql/persisted_queries/store_adapters/memcached_store_adapter.rb
|
131
147
|
- lib/graphql/persisted_queries/store_adapters/memory_store_adapter.rb
|
132
148
|
- lib/graphql/persisted_queries/store_adapters/redis_client_builder.rb
|
133
149
|
- lib/graphql/persisted_queries/store_adapters/redis_store_adapter.rb
|