graphql-persisted_queries 0.1.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 +7 -0
- data/.gitignore +9 -0
- data/.rubocop.yml +26 -0
- data/.travis.yml +23 -0
- data/CHANGELOG.md +9 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +100 -0
- data/Rakefile +8 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/gemfiles/graphql_1_8.gemfile +5 -0
- data/gemfiles/graphql_1_9.gemfile +5 -0
- data/gemfiles/graphql_master.gemfile +5 -0
- data/graphql-persisted_queries.gemspec +31 -0
- data/lib/graphql/persisted_queries.rb +16 -0
- data/lib/graphql/persisted_queries/hash_generator_builder.rb +40 -0
- data/lib/graphql/persisted_queries/resolver.rb +53 -0
- data/lib/graphql/persisted_queries/schema_patch.rb +32 -0
- data/lib/graphql/persisted_queries/store_adapters.rb +28 -0
- data/lib/graphql/persisted_queries/store_adapters/base_store_adapter.rb +20 -0
- data/lib/graphql/persisted_queries/store_adapters/memory_store_adapter.rb +22 -0
- data/lib/graphql/persisted_queries/store_adapters/redis_store_adapter.rb +66 -0
- data/lib/graphql/persisted_queries/version.rb +7 -0
- metadata +136 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c766b357d35d1bda4dfba34a5a633260a0dfe3593189f1d60b35d5973b5c18a4
|
4
|
+
data.tar.gz: 6182e3cdb5ce2ed6194b7ee4eef87ad2c3194299904bd1ecaf29fc5179c1358e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6ee805aae51f2ecf5c055eb5c3d02b20873369a990498f0b2e75348ab62cf8192945b9716d87c616772e2c07b000fd8b73a238e45124cd7e849e3d3041e41cf6
|
7
|
+
data.tar.gz: 49b7cbe475f09c7f4ec6e4b11a1dbcb3d86a03fcd6d63ef4acf977e59aff6c6e223e858d24f96f6895d8ccee9495f0ffbd623a28e48eec89ccd895fa284cd4d0
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.6
|
3
|
+
Include:
|
4
|
+
- 'lib/**/*.rb'
|
5
|
+
- 'spec/**/*.rb'
|
6
|
+
Exclude:
|
7
|
+
- 'bin/**/*'
|
8
|
+
- 'vendor/**/*'
|
9
|
+
- 'gemfiles/**/*.gemfile'
|
10
|
+
- 'gemfiles/vendor/**/*'
|
11
|
+
- 'Rakefile'
|
12
|
+
- 'Gemfile'
|
13
|
+
- '*.gemspec'
|
14
|
+
|
15
|
+
Style/StringLiterals:
|
16
|
+
EnforcedStyle: double_quotes
|
17
|
+
|
18
|
+
Metrics/LineLength:
|
19
|
+
Max: 100
|
20
|
+
|
21
|
+
Metrics/BlockLength:
|
22
|
+
Exclude:
|
23
|
+
- 'spec/**/*.rb'
|
24
|
+
|
25
|
+
Style/NumericLiterals:
|
26
|
+
Enabled: false
|
data/.travis.yml
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
language: ruby
|
2
|
+
cache: bundler
|
3
|
+
|
4
|
+
sudo: false
|
5
|
+
|
6
|
+
rvm:
|
7
|
+
- 2.3
|
8
|
+
- 2.4
|
9
|
+
- 2.5
|
10
|
+
- 2.6
|
11
|
+
- ruby-head
|
12
|
+
|
13
|
+
gemfile:
|
14
|
+
- gemfiles/graphql_1_8.gemfile
|
15
|
+
- gemfiles/graphql_1_9.gemfile
|
16
|
+
- gemfiles/graphql_master.gemfile
|
17
|
+
|
18
|
+
|
19
|
+
notifications:
|
20
|
+
email: false
|
21
|
+
|
22
|
+
matrix:
|
23
|
+
fast_finish: true
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 DmitryTsepelev
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# GraphQL::PersistedQueries [](https://travis-ci.org/DmitryTsepelev/graphql-ruby-persisted_queries)
|
2
|
+
|
3
|
+
|
4
|
+
`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
|
+
|
6
|
+
- 🗑**Heavy query parameter will be omitted in most of cases** – network requests will become less heavy
|
7
|
+
- 🤝**Clients share cached queries** – it's enough to miss cache only once for each unique query
|
8
|
+
- 🎅**Works for clients without persisted query support**
|
9
|
+
|
10
|
+
|
11
|
+
<p align="center">
|
12
|
+
<a href="https://evilmartians.com/?utm_source=graphql-ruby-persisted_queries">
|
13
|
+
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54">
|
14
|
+
</a>
|
15
|
+
</p>
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
1. Add the gem to your Gemfile `gem 'graphql-persisted_queries'`
|
20
|
+
|
21
|
+
2. Install and configure [apollo-link-persisted-queries](https://github.com/apollographql/apollo-link-persisted-queries):
|
22
|
+
|
23
|
+
```js
|
24
|
+
import { createPersistedQueryLink } from "apollo-link-persisted-queries";
|
25
|
+
import { createHttpLink } from "apollo-link-http";
|
26
|
+
import { InMemoryCache } from "apollo-cache-inmemory";
|
27
|
+
import ApolloClient from "apollo-client";
|
28
|
+
|
29
|
+
|
30
|
+
// use this with Apollo Client
|
31
|
+
const link = createPersistedQueryLink().concat(createHttpLink({ uri: "/graphql" }));
|
32
|
+
const client = new ApolloClient({
|
33
|
+
cache: new InMemoryCache(),
|
34
|
+
link: link,
|
35
|
+
});
|
36
|
+
```
|
37
|
+
|
38
|
+
3. Add plugin to the schema:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
class GraphqlSchema < GraphQL::Schema
|
42
|
+
use GraphQL::PersistedQueries
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
4. Pass `:extensions` argument to all calls of `GraphqlSchema#execute` (start with `GraphqlController` and `GraphqlChannel`)
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
GraphqlSchema.execute(
|
50
|
+
params[:query],
|
51
|
+
variables: ensure_hash(params[:variables]),
|
52
|
+
context: {},
|
53
|
+
operation_name: params[:operationName],
|
54
|
+
extensions: ensure_hash(params[:extensions])
|
55
|
+
)
|
56
|
+
```
|
57
|
+
|
58
|
+
5. Run the app! 🔥
|
59
|
+
|
60
|
+
## Alternative stores
|
61
|
+
|
62
|
+
All the queries are stored in memory by default, but you can easily switch to _redis_:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
class GraphqlSchema < GraphQL::Schema
|
66
|
+
use GraphQL::PersistedQueries, store: :redis, redis_url: ENV["MY_REDIS_URL"]
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
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` to build the URL from scratch or configure Redis client as you want and pass it as the `:client` option.
|
71
|
+
|
72
|
+
## Alternative hash functions
|
73
|
+
|
74
|
+
[apollo-link-persisted-queries](https://github.com/apollographql/apollo-link-persisted-queries) uses _SHA256_ by default so this gem uses it as a default too, but if you want to override it – you can use `:hash_generator` option:
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
class GraphqlSchema < GraphQL::Schema
|
78
|
+
use GraphQL::PersistedQueries, hash_generator: :md5
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
82
|
+
If string or symbol is passed – the gem would try to find the class in the `Digest` namespace. Altenatively, you can pass a lambda, e.g.:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
class GraphqlSchema < GraphQL::Schema
|
86
|
+
use GraphQL::PersistedQueries, hash_generator: proc { |_value| "super_safe_hash!!!" }
|
87
|
+
end
|
88
|
+
```
|
89
|
+
|
90
|
+
## GET requests and HTTP cache
|
91
|
+
|
92
|
+
Using `GET` requests for persisted queries allows you to enable HTTP caching (e.g., turn on CDN). In order to make it work you should change the way link is initialized on front-end side (`createPersistedQueryLink({ useGETForHashedQueries: true })`) and register a new route `get "/graphql", to: "graphql#execute"`.
|
93
|
+
|
94
|
+
## Contributing
|
95
|
+
|
96
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/DmitryTsepelev/graphql-persisted_queries.
|
97
|
+
|
98
|
+
## License
|
99
|
+
|
100
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "graphql/persisted_queries"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
lib = File.expand_path("lib", __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "graphql/persisted_queries/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "graphql-persisted_queries"
|
7
|
+
spec.version = GraphQL::PersistedQueries::VERSION
|
8
|
+
spec.authors = ["DmitryTsepelev"]
|
9
|
+
spec.email = ["dmitry.a.tsepelev@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "Persisted queries for graphql-ruby"
|
12
|
+
spec.description = "Persisted queries for graphql-ruby"
|
13
|
+
spec.homepage = "https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
17
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
end
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.required_ruby_version = ">= 2.3"
|
24
|
+
|
25
|
+
spec.add_dependency "graphql", ">= 1.8"
|
26
|
+
|
27
|
+
spec.add_development_dependency "rspec", "~> 3.9"
|
28
|
+
spec.add_development_dependency "rake", ">= 10.0"
|
29
|
+
spec.add_development_dependency "rubocop", "0.75"
|
30
|
+
spec.add_development_dependency "redis"
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "graphql/persisted_queries/schema_patch"
|
4
|
+
require "graphql/persisted_queries/store_adapters"
|
5
|
+
require "graphql/persisted_queries/version"
|
6
|
+
|
7
|
+
module GraphQL
|
8
|
+
# Plugin definition
|
9
|
+
module PersistedQueries
|
10
|
+
def self.use(schema_defn, store: :memory, hash_generator: :sha256, **options)
|
11
|
+
schema_defn.target.singleton_class.prepend(SchemaPatch)
|
12
|
+
schema_defn.target.hash_generator = hash_generator
|
13
|
+
schema_defn.target.configure_persisted_query_store(store, options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "digest"
|
4
|
+
|
5
|
+
module GraphQL
|
6
|
+
module PersistedQueries
|
7
|
+
# Builds hash generator
|
8
|
+
class HashGeneratorBuilder
|
9
|
+
def initialize(generator)
|
10
|
+
@generator = generator
|
11
|
+
end
|
12
|
+
|
13
|
+
def build
|
14
|
+
if @generator.is_a?(Proc)
|
15
|
+
build_from_proc
|
16
|
+
else
|
17
|
+
build_from_name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def build_from_proc
|
24
|
+
if @generator.arity != 1
|
25
|
+
raise ArgumentError, "proc passed to :hash_generator should have exactly one argument"
|
26
|
+
end
|
27
|
+
|
28
|
+
@generator
|
29
|
+
end
|
30
|
+
|
31
|
+
def build_from_name
|
32
|
+
upcased_name = @generator.to_s.upcase
|
33
|
+
digest_class = Digest.const_get(upcased_name)
|
34
|
+
proc { |value| digest_class.hexdigest(value) }
|
35
|
+
rescue LoadError => e
|
36
|
+
raise NameError, "digest class for :#{@generator} haven't been found", e.backtrace
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module PersistedQueries
|
5
|
+
# Fetches or stores query string in the storage
|
6
|
+
class Resolver
|
7
|
+
# Raised when persisted query is not found in the storage
|
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
|
20
|
+
|
21
|
+
def initialize(extensions, store, hash_generator_proc)
|
22
|
+
@extensions = extensions
|
23
|
+
@store = store
|
24
|
+
@hash_generator_proc = hash_generator_proc
|
25
|
+
end
|
26
|
+
|
27
|
+
def resolve(query_str)
|
28
|
+
return query_str if hash.nil?
|
29
|
+
|
30
|
+
if query_str
|
31
|
+
persist_query(query_str)
|
32
|
+
else
|
33
|
+
query_str = @store.fetch_query(hash)
|
34
|
+
raise NotFound if query_str.nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
query_str
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def persist_query(query_str)
|
43
|
+
raise WrongHash if @hash_generator_proc.call(query_str) != hash
|
44
|
+
|
45
|
+
@store.save_query(hash, query_str)
|
46
|
+
end
|
47
|
+
|
48
|
+
def hash
|
49
|
+
@hash ||= @extensions.dig("persistedQuery", "sha256Hash")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "graphql/persisted_queries/hash_generator_builder"
|
4
|
+
require "graphql/persisted_queries/resolver"
|
5
|
+
|
6
|
+
module GraphQL
|
7
|
+
module PersistedQueries
|
8
|
+
# Patches GraphQL::Schema to support persisted queries
|
9
|
+
module SchemaPatch
|
10
|
+
attr_reader :persisted_query_store, :hash_generator_proc
|
11
|
+
|
12
|
+
def configure_persisted_query_store(store, options)
|
13
|
+
@persisted_query_store = StoreAdapters.build(store, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def hash_generator=(hash_generator)
|
17
|
+
@hash_generator_proc = HashGeneratorBuilder.new(hash_generator).build
|
18
|
+
end
|
19
|
+
|
20
|
+
def execute(query_str = nil, **kwargs)
|
21
|
+
if (extensions = kwargs.delete(:extensions))
|
22
|
+
resolver = Resolver.new(extensions, persisted_query_store, hash_generator_proc)
|
23
|
+
query_str = resolver.resolve(query_str)
|
24
|
+
end
|
25
|
+
|
26
|
+
super
|
27
|
+
rescue Resolver::NotFound, Resolver::WrongHash => e
|
28
|
+
{ errors: [{ message: e.message }] }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "graphql/persisted_queries/store_adapters/base_store_adapter"
|
4
|
+
require "graphql/persisted_queries/store_adapters/memory_store_adapter"
|
5
|
+
require "graphql/persisted_queries/store_adapters/redis_store_adapter"
|
6
|
+
|
7
|
+
module GraphQL
|
8
|
+
module PersistedQueries
|
9
|
+
# Contains factory methods for store adapters
|
10
|
+
module StoreAdapters
|
11
|
+
def self.build(adapter, options = nil)
|
12
|
+
if adapter.is_a?(StoreAdapters::BaseStoreAdapter)
|
13
|
+
adapter
|
14
|
+
else
|
15
|
+
build_by_name(adapter, options)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.build_by_name(name, options)
|
20
|
+
camelized_adapter = name.to_s.split("_").map(&:capitalize).join
|
21
|
+
adapter_class_name = "#{camelized_adapter}StoreAdapter"
|
22
|
+
StoreAdapters.const_get(adapter_class_name).new(options || {})
|
23
|
+
rescue NameError => e
|
24
|
+
raise e.class, "Persisted query store adapter for :#{name} haven't been found", e.backtrace
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module PersistedQueries
|
5
|
+
module StoreAdapters
|
6
|
+
# Base class for all store adapters
|
7
|
+
class BaseStoreAdapter
|
8
|
+
def initialize(_options); end
|
9
|
+
|
10
|
+
def fetch_query(_hash)
|
11
|
+
raise NotImplementedError
|
12
|
+
end
|
13
|
+
|
14
|
+
def save_query(_hash, _query)
|
15
|
+
raise NotImplementedError
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module PersistedQueries
|
5
|
+
module StoreAdapters
|
6
|
+
# Memory adapter for storing persisted queries
|
7
|
+
class MemoryStoreAdapter < BaseStoreAdapter
|
8
|
+
def initialize(_options)
|
9
|
+
@storage = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def fetch_query(hash)
|
13
|
+
@storage[hash]
|
14
|
+
end
|
15
|
+
|
16
|
+
def save_query(hash, query)
|
17
|
+
@storage[hash] = query
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module PersistedQueries
|
5
|
+
module StoreAdapters
|
6
|
+
# Redis adapter for storing persisted queries
|
7
|
+
class RedisStoreAdapter < BaseStoreAdapter
|
8
|
+
attr_reader :storage
|
9
|
+
|
10
|
+
def initialize(client: nil, **options)
|
11
|
+
require "redis"
|
12
|
+
|
13
|
+
if client && options.any?
|
14
|
+
raise ArgumentError, "client cannot be passed along with redis_url, redis_host" \
|
15
|
+
", redis_port or redis_db_name options"
|
16
|
+
end
|
17
|
+
|
18
|
+
@storage = client || configure_redis_client(options)
|
19
|
+
rescue LoadError => e
|
20
|
+
msg = "Could not load the 'redis' gem, please add it to your gemfile or " \
|
21
|
+
"configure a different adapter, e.g. use GraphQL::PersistedQueries, store: :memory"
|
22
|
+
raise e.class, msg, e.backtrace
|
23
|
+
end
|
24
|
+
|
25
|
+
def fetch_query(hash)
|
26
|
+
storage.get(key_for(hash))
|
27
|
+
end
|
28
|
+
|
29
|
+
def save_query(hash, query)
|
30
|
+
storage.set(key_for(hash), query)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def key_for(hash)
|
36
|
+
"persisted-query-#{hash}"
|
37
|
+
end
|
38
|
+
|
39
|
+
# rubocop:disable Metrics/LineLength
|
40
|
+
def configure_redis_client(redis_url: nil, redis_host: nil, redis_port: nil, redis_db_name: nil)
|
41
|
+
if redis_url && (redis_host || redis_port || redis_db_name)
|
42
|
+
raise ArgumentError, "redis_url cannot be passed along with redis_host, redis_port " \
|
43
|
+
"or redis_db_name options"
|
44
|
+
end
|
45
|
+
|
46
|
+
redis_url ||= build_redis_url(
|
47
|
+
redis_host: redis_host,
|
48
|
+
redis_port: redis_port,
|
49
|
+
redis_db_name: redis_db_name
|
50
|
+
)
|
51
|
+
|
52
|
+
Redis.new(url: redis_url)
|
53
|
+
end
|
54
|
+
# rubocop:enable Metrics/LineLength
|
55
|
+
|
56
|
+
DEFAULT_REDIS_DB = "0"
|
57
|
+
|
58
|
+
def build_redis_url(redis_host: nil, redis_port: nil, redis_db_name: nil)
|
59
|
+
redis_db_name ||= DEFAULT_REDIS_DB
|
60
|
+
redis_base_url = ENV["REDIS_URL"] || "redis://#{redis_host}:#{redis_port}"
|
61
|
+
URI.join(redis_base_url, redis_db_name).to_s
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
metadata
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: graphql-persisted_queries
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- DmitryTsepelev
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-10-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: graphql
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.8'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.8'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.9'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.75'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.75'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: redis
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Persisted queries for graphql-ruby
|
84
|
+
email:
|
85
|
+
- dmitry.a.tsepelev@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".rubocop.yml"
|
92
|
+
- ".travis.yml"
|
93
|
+
- CHANGELOG.md
|
94
|
+
- Gemfile
|
95
|
+
- LICENSE.txt
|
96
|
+
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- bin/console
|
99
|
+
- bin/setup
|
100
|
+
- gemfiles/graphql_1_8.gemfile
|
101
|
+
- gemfiles/graphql_1_9.gemfile
|
102
|
+
- gemfiles/graphql_master.gemfile
|
103
|
+
- graphql-persisted_queries.gemspec
|
104
|
+
- lib/graphql/persisted_queries.rb
|
105
|
+
- lib/graphql/persisted_queries/hash_generator_builder.rb
|
106
|
+
- lib/graphql/persisted_queries/resolver.rb
|
107
|
+
- lib/graphql/persisted_queries/schema_patch.rb
|
108
|
+
- lib/graphql/persisted_queries/store_adapters.rb
|
109
|
+
- lib/graphql/persisted_queries/store_adapters/base_store_adapter.rb
|
110
|
+
- lib/graphql/persisted_queries/store_adapters/memory_store_adapter.rb
|
111
|
+
- lib/graphql/persisted_queries/store_adapters/redis_store_adapter.rb
|
112
|
+
- lib/graphql/persisted_queries/version.rb
|
113
|
+
homepage: https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries
|
114
|
+
licenses:
|
115
|
+
- MIT
|
116
|
+
metadata: {}
|
117
|
+
post_install_message:
|
118
|
+
rdoc_options: []
|
119
|
+
require_paths:
|
120
|
+
- lib
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '2.3'
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
requirements: []
|
132
|
+
rubygems_version: 3.0.3
|
133
|
+
signing_key:
|
134
|
+
specification_version: 4
|
135
|
+
summary: Persisted queries for graphql-ruby
|
136
|
+
test_files: []
|