graphql-result_cache 0.1.1 → 0.1.2
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/Gemfile.lock +1 -1
- data/README.md +24 -0
- data/lib/graphql/result_cache/callback.rb +22 -0
- data/lib/graphql/result_cache/context_config.rb +10 -3
- data/lib/graphql/result_cache/field_instrument.rb +4 -3
- data/lib/graphql/result_cache/key.rb +1 -1
- data/lib/graphql/result_cache/version.rb +1 -1
- data/lib/graphql/result_cache.rb +4 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a82a463a163e049de4904d6c8ccc2dcd434ba9f2d9b8cc290a607691b7444086
|
4
|
+
data.tar.gz: a1614159c06e2924a3a11c082bae2668da3acd315ddc881ed70d01a9889ef6a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5437965558d61fbb534ac2cef46c51b70f9a1ba08550dc3aece6b474bb3501b7fbcd53a386f999f5efbe776c0e41fb56bef632c3a5c238687bd516fb6503a46
|
7
|
+
data.tar.gz: bf03d88d2fa2a4fab03522f1b14321ddf35076ae3781a4e545c0f683d25b5d1c5d03f25364fa74deb2c350f5becb9ba0b1c4cabf452b9a602cbb41b93cee640d
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -82,6 +82,18 @@ field :theme, Types::ThemeType, null: false, result_cache: { key: :theme_cache_k
|
|
82
82
|
```
|
83
83
|
The `key` can be either a Symbol or a Proc.
|
84
84
|
|
85
|
+
### Callback after cached result applied
|
86
|
+
|
87
|
+
An `after_process` callback can be provided, eg. when some dynamic values need to be amended after cached result applied.
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
field :theme, Types::ThemeType, null: false, result_cache: { after_process: :amend_dynamic_attributes }
|
91
|
+
|
92
|
+
def amend_dynamic_attributes(theme_node)
|
93
|
+
theme_node.merge! used_count: object.theme.used_count
|
94
|
+
end
|
95
|
+
```
|
96
|
+
|
85
97
|
## Global Configuration
|
86
98
|
|
87
99
|
`GraphQL::ResultCache` can be configured in initializer.
|
@@ -98,6 +110,18 @@ GraphQL::ResultCache.configure do |config|
|
|
98
110
|
end
|
99
111
|
```
|
100
112
|
|
113
|
+
When the query is an introspection, you can set the value to avoid getting the nullable type for a non-null type.
|
114
|
+
```ruby
|
115
|
+
class GraphqlController < ApplicationController
|
116
|
+
def execute
|
117
|
+
# ...
|
118
|
+
GraphQL::ResultCache.introspection = params[:query].include? '__schema'
|
119
|
+
result = MySchema.execute(params[:query], variables: ensure_hash(params[:variables]), context: context, operation_name: params[:operationName])
|
120
|
+
render json: GraphQL::ResultCache::Result.new(result)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
```
|
124
|
+
|
101
125
|
## Development
|
102
126
|
|
103
127
|
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module GraphQL
|
2
|
+
module ResultCache
|
3
|
+
class Callback
|
4
|
+
def initialize obj:, args:, ctx:, value:
|
5
|
+
@obj = obj
|
6
|
+
@args = args
|
7
|
+
@ctx = ctx
|
8
|
+
@value = value
|
9
|
+
end
|
10
|
+
|
11
|
+
def call result_hash
|
12
|
+
case @value
|
13
|
+
when Symbol
|
14
|
+
@obj.public_send(@value, result_hash)
|
15
|
+
when Proc
|
16
|
+
@value.call(result_hash, @obj, @args, @ctx)
|
17
|
+
end
|
18
|
+
::GraphQL::ResultCache.logger&.debug "GraphQL result cache callback called for #{@ctx.path.join('.')}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -8,11 +8,16 @@ module GraphQL
|
|
8
8
|
@value = {}
|
9
9
|
end
|
10
10
|
|
11
|
-
def add context:, key:
|
11
|
+
def add context:, key:, after_process: nil
|
12
12
|
@value[context.query] ||= []
|
13
13
|
cached = cache.exist? key
|
14
14
|
logger&.info "GraphQL result cache key #{cached ? 'hit' : 'miss'}: #{key}"
|
15
|
-
|
15
|
+
config_value = { path: context.path, key: key }
|
16
|
+
if cached
|
17
|
+
config_value[:result] = cache.read(key)
|
18
|
+
config_value[:after_process] = after_process if after_process
|
19
|
+
end
|
20
|
+
@value[context.query] << config_value
|
16
21
|
cached
|
17
22
|
end
|
18
23
|
|
@@ -37,7 +42,9 @@ module GraphQL
|
|
37
42
|
cache.write config[:key], result.dig('data', *config[:path]), expires_in: expires_in
|
38
43
|
else
|
39
44
|
# result already got from cache, need to amend to response
|
40
|
-
|
45
|
+
result_hash = result.to_h
|
46
|
+
deep_merge! result_hash, 'data' => config[:path].reverse.inject(config[:result]) { |a, n| {n => a} }
|
47
|
+
config[:after_process]&.call(result_hash.dig('data', *config[:path]))
|
41
48
|
end
|
42
49
|
end
|
43
50
|
result
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'graphql/result_cache/condition'
|
2
2
|
require 'graphql/result_cache/context_config'
|
3
3
|
require 'graphql/result_cache/key'
|
4
|
+
require 'graphql/result_cache/callback'
|
4
5
|
|
5
6
|
module GraphQL
|
6
7
|
module ResultCache
|
@@ -11,8 +12,7 @@ module GraphQL
|
|
11
12
|
cached_resolve_proc = cached_resolve(field)
|
12
13
|
field.redefine do
|
13
14
|
resolve(cached_resolve_proc)
|
14
|
-
|
15
|
-
type(field.type.of_type) if field.type.non_null?
|
15
|
+
type(field.type.of_type) if !::GraphQL::ResultCache.introspection? && field.type.non_null?
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -26,7 +26,8 @@ module GraphQL
|
|
26
26
|
if Condition.new(cache_config, obj: obj, args: args, ctx: ctx).true?
|
27
27
|
ctx[:result_cache] ||= ContextConfig.new
|
28
28
|
cache_key = Key.new(obj: obj, args: args, ctx: ctx, key: cache_config[:key])
|
29
|
-
|
29
|
+
after_process = Callback.new(obj: obj, args: args, ctx: ctx, value: cache_config[:after_process]) if cache_config[:after_process]
|
30
|
+
cached = ctx[:result_cache].add context: ctx, key: cache_key.to_s, after_process: after_process
|
30
31
|
end
|
31
32
|
old_resolve_proc.call(obj, args, ctx) unless cached
|
32
33
|
end
|
data/lib/graphql/result_cache.rb
CHANGED
@@ -16,6 +16,9 @@ module GraphQL
|
|
16
16
|
# c.client_hash = -> { Rails.cache.read(:deploy_version) }
|
17
17
|
attr_accessor :client_hash
|
18
18
|
|
19
|
+
attr_accessor :introspection
|
20
|
+
alias introspection? introspection
|
21
|
+
|
19
22
|
# ```
|
20
23
|
# GraphQL::ResultCache.configure do |c|
|
21
24
|
# c.namespace = "GraphQL:Result"
|
@@ -31,6 +34,7 @@ module GraphQL
|
|
31
34
|
# Default configuration
|
32
35
|
@expires_in = 3600 # 1.hour
|
33
36
|
@namespace = 'GraphQL:Result'
|
37
|
+
@introspection = false
|
34
38
|
|
35
39
|
def self.use(schema_def, options: {})
|
36
40
|
schema_def.instrument(:field, ::GraphQL::ResultCache::FieldInstrument.new)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql-result_cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ying Fu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -85,6 +85,7 @@ files:
|
|
85
85
|
- bin/setup
|
86
86
|
- graphql-result_cache.gemspec
|
87
87
|
- lib/graphql/result_cache.rb
|
88
|
+
- lib/graphql/result_cache/callback.rb
|
88
89
|
- lib/graphql/result_cache/condition.rb
|
89
90
|
- lib/graphql/result_cache/context_config.rb
|
90
91
|
- lib/graphql/result_cache/field.rb
|