graphql-persisted_queries 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +27 -0
- data/lib/graphql/persisted_queries.rb +5 -1
- data/lib/graphql/persisted_queries/builder_helpers.rb +12 -0
- data/lib/graphql/persisted_queries/error_handlers.rb +35 -0
- data/lib/graphql/persisted_queries/error_handlers/base_error_handler.rb +16 -0
- data/lib/graphql/persisted_queries/error_handlers/default_error_handler.rb +14 -0
- data/lib/graphql/persisted_queries/resolver.rb +10 -3
- data/lib/graphql/persisted_queries/schema_patch.rb +7 -2
- data/lib/graphql/persisted_queries/store_adapters.rb +1 -3
- data/lib/graphql/persisted_queries/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3121fbd184f715130c9f9f1956dcd89c24d52507d23ac0b35a408a9d53d54e72
|
4
|
+
data.tar.gz: 7e4b32a6b5d0fda8d9b135a435bca92587749ccb61664f37092c593ef4b04eb0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a42f753183b5d8aa8c0d8f321a988b61375ad6ae828ef9c232e91f4f20adb5da824b6b095cb034af805e11039f5c7122d52add4cdb4caa36bb873335a85e5847
|
7
|
+
data.tar.gz: 539d3e7da1bed8a470555b2b411cd52a6631663e7f3927e0c9252988488800c205bfe10f4eb03b3baa34899e286420b9d743f411fefc54c9dc091a1406d75a96
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.2.0 (2020-02-11)
|
6
|
+
|
7
|
+
- [PR#17](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/17) Allow an optional custom error handler so that implementors can control failure scenarios when query resolution fails ([@bmorton][])
|
8
|
+
|
5
9
|
## 0.1.3 (2020-01-30)
|
6
10
|
|
7
11
|
- [PR#15](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/15) Allow optional custom expiration and namespace for Redis store ([@bmorton][])
|
data/README.md
CHANGED
@@ -115,6 +115,33 @@ class GraphqlSchema < GraphQL::Schema
|
|
115
115
|
end
|
116
116
|
```
|
117
117
|
|
118
|
+
## Error handling
|
119
|
+
|
120
|
+
You may optionally specify an object that will be called whenever an error occurs while attempting to resolve or save a query. This will give you the opportunity to both handle (e.g. graceful Redis failure) and/or log the error. By default, errors will be raised when a failure occurs within a `StoreAdapter`.
|
121
|
+
|
122
|
+
An error handler can be a proc or an implementation of `GraphQL::PersistedQueries::ErrorHandlers::BaseErrorHandler`. Here's an example for treating Redis failures as cache misses:
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
class GracefulRedisErrorHandler < GraphQL::PersistedQueries::ErrorHandlers::BaseErrorHandler
|
126
|
+
def call(error)
|
127
|
+
case error
|
128
|
+
when Redis::BaseError
|
129
|
+
# Treat Redis errors as a cache miss, but you should log the error into
|
130
|
+
# your instrumentation framework here.
|
131
|
+
else
|
132
|
+
raise error
|
133
|
+
end
|
134
|
+
|
135
|
+
# Return nothing to ensure handled errors are treated as cache misses
|
136
|
+
return
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
class GraphqlSchema < GraphQL::Schema
|
141
|
+
use GraphQL::PersistedQueries, error_handler: GracefulRedisErrorHandler.new
|
142
|
+
end
|
143
|
+
```
|
144
|
+
|
118
145
|
## GET requests and HTTP cache
|
119
146
|
|
120
147
|
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"`.
|
@@ -1,17 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "graphql/persisted_queries/error_handlers"
|
3
4
|
require "graphql/persisted_queries/schema_patch"
|
4
5
|
require "graphql/persisted_queries/store_adapters"
|
5
6
|
require "graphql/persisted_queries/version"
|
7
|
+
require "graphql/persisted_queries/builder_helpers"
|
6
8
|
|
7
9
|
module GraphQL
|
8
10
|
# Plugin definition
|
9
11
|
module PersistedQueries
|
10
|
-
def self.use(schema_defn, store: :memory, hash_generator: :sha256,
|
12
|
+
def self.use(schema_defn, store: :memory, hash_generator: :sha256,
|
13
|
+
error_handler: :default, **options)
|
11
14
|
schema = schema_defn.is_a?(Class) ? schema_defn : schema_defn.target
|
12
15
|
|
13
16
|
schema.singleton_class.prepend(SchemaPatch)
|
14
17
|
schema.hash_generator = hash_generator
|
18
|
+
schema.configure_persisted_query_error_handler(error_handler)
|
15
19
|
schema.configure_persisted_query_store(store, options)
|
16
20
|
end
|
17
21
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "graphql/persisted_queries/error_handlers/base_error_handler"
|
4
|
+
require "graphql/persisted_queries/error_handlers/default_error_handler"
|
5
|
+
|
6
|
+
module GraphQL
|
7
|
+
module PersistedQueries
|
8
|
+
# Contains factory methods for error handlers
|
9
|
+
module ErrorHandlers
|
10
|
+
def self.build(handler, options = nil)
|
11
|
+
if handler.is_a?(ErrorHandlers::BaseErrorHandler)
|
12
|
+
handler
|
13
|
+
elsif handler.is_a?(Proc)
|
14
|
+
build_from_proc(handler)
|
15
|
+
else
|
16
|
+
build_by_name(handler, options)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.build_from_proc(proc)
|
21
|
+
if proc.arity != 1
|
22
|
+
raise ArgumentError, "proc passed to :error_handler should have exactly one argument"
|
23
|
+
end
|
24
|
+
|
25
|
+
proc
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.build_by_name(name, options)
|
29
|
+
const_get("#{BuilderHelpers.camelize(name)}ErrorHandler").new(options || {})
|
30
|
+
rescue NameError => e
|
31
|
+
raise e.class, "Persisted query error handler for :#{name} haven't been found", e.backtrace
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module PersistedQueries
|
5
|
+
module ErrorHandlers
|
6
|
+
# Base class for all error handlers
|
7
|
+
class BaseErrorHandler
|
8
|
+
def initialize(_options); end
|
9
|
+
|
10
|
+
def call(_error)
|
11
|
+
raise NotImplementedError
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module PersistedQueries
|
5
|
+
module ErrorHandlers
|
6
|
+
# Default error handler for simply re-raising the error
|
7
|
+
class DefaultErrorHandler < BaseErrorHandler
|
8
|
+
def call(error)
|
9
|
+
raise error
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -18,10 +18,11 @@ module GraphQL
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
def initialize(extensions, store, hash_generator_proc)
|
21
|
+
def initialize(extensions, store, hash_generator_proc, error_handler)
|
22
22
|
@extensions = extensions
|
23
23
|
@store = store
|
24
24
|
@hash_generator_proc = hash_generator_proc
|
25
|
+
@error_handler = error_handler
|
25
26
|
end
|
26
27
|
|
27
28
|
def resolve(query_str)
|
@@ -30,7 +31,7 @@ module GraphQL
|
|
30
31
|
if query_str
|
31
32
|
persist_query(query_str)
|
32
33
|
else
|
33
|
-
query_str = @store.fetch_query(hash)
|
34
|
+
query_str = with_error_handling { @store.fetch_query(hash) }
|
34
35
|
raise NotFound if query_str.nil?
|
35
36
|
end
|
36
37
|
|
@@ -39,10 +40,16 @@ module GraphQL
|
|
39
40
|
|
40
41
|
private
|
41
42
|
|
43
|
+
def with_error_handling
|
44
|
+
yield
|
45
|
+
rescue StandardError => e
|
46
|
+
@error_handler.call(e)
|
47
|
+
end
|
48
|
+
|
42
49
|
def persist_query(query_str)
|
43
50
|
raise WrongHash if @hash_generator_proc.call(query_str) != hash
|
44
51
|
|
45
|
-
@store.save_query(hash, query_str)
|
52
|
+
with_error_handling { @store.save_query(hash, query_str) }
|
46
53
|
end
|
47
54
|
|
48
55
|
def hash
|
@@ -7,19 +7,24 @@ module GraphQL
|
|
7
7
|
module PersistedQueries
|
8
8
|
# Patches GraphQL::Schema to support persisted queries
|
9
9
|
module SchemaPatch
|
10
|
-
attr_reader :persisted_query_store, :hash_generator_proc
|
10
|
+
attr_reader :persisted_query_store, :hash_generator_proc, :persisted_query_error_handler
|
11
11
|
|
12
12
|
def configure_persisted_query_store(store, options)
|
13
13
|
@persisted_query_store = StoreAdapters.build(store, options)
|
14
14
|
end
|
15
15
|
|
16
|
+
def configure_persisted_query_error_handler(handler)
|
17
|
+
@persisted_query_error_handler = ErrorHandlers.build(handler)
|
18
|
+
end
|
19
|
+
|
16
20
|
def hash_generator=(hash_generator)
|
17
21
|
@hash_generator_proc = HashGeneratorBuilder.new(hash_generator).build
|
18
22
|
end
|
19
23
|
|
20
24
|
def execute(query_str = nil, **kwargs)
|
21
25
|
if (extensions = kwargs.delete(:extensions))
|
22
|
-
resolver = Resolver.new(extensions, persisted_query_store, hash_generator_proc
|
26
|
+
resolver = Resolver.new(extensions, persisted_query_store, hash_generator_proc,
|
27
|
+
persisted_query_error_handler)
|
23
28
|
query_str = resolver.resolve(query_str)
|
24
29
|
end
|
25
30
|
|
@@ -17,9 +17,7 @@ module GraphQL
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.build_by_name(name, options)
|
20
|
-
|
21
|
-
adapter_class_name = "#{camelized_adapter}StoreAdapter"
|
22
|
-
StoreAdapters.const_get(adapter_class_name).new(options || {})
|
20
|
+
const_get("#{BuilderHelpers.camelize(name)}StoreAdapter").new(options || {})
|
23
21
|
rescue NameError => e
|
24
22
|
raise e.class, "Persisted query store adapter for :#{name} haven't been found", e.backtrace
|
25
23
|
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.2.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-
|
11
|
+
date: 2020-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -117,6 +117,10 @@ files:
|
|
117
117
|
- gemfiles/graphql_master.gemfile
|
118
118
|
- graphql-persisted_queries.gemspec
|
119
119
|
- lib/graphql/persisted_queries.rb
|
120
|
+
- lib/graphql/persisted_queries/builder_helpers.rb
|
121
|
+
- lib/graphql/persisted_queries/error_handlers.rb
|
122
|
+
- lib/graphql/persisted_queries/error_handlers/base_error_handler.rb
|
123
|
+
- lib/graphql/persisted_queries/error_handlers/default_error_handler.rb
|
120
124
|
- lib/graphql/persisted_queries/hash_generator_builder.rb
|
121
125
|
- lib/graphql/persisted_queries/resolver.rb
|
122
126
|
- lib/graphql/persisted_queries/schema_patch.rb
|