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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba79fe918d359fba4d366fd3becfd4779860b3af1c4083c634578bba7258fbf9
4
- data.tar.gz: 814addd76ffa4ccb92a4641d27c58d71d0359005eff4e1bc9145cd6d47cf2b0b
3
+ metadata.gz: a82a463a163e049de4904d6c8ccc2dcd434ba9f2d9b8cc290a607691b7444086
4
+ data.tar.gz: a1614159c06e2924a3a11c082bae2668da3acd315ddc881ed70d01a9889ef6a5
5
5
  SHA512:
6
- metadata.gz: 7a8cb8d375f740c870acd94feaafded3d38e911acafa73573748ff63c49c9134e844488308a054ab601daafe56fa6af23a71bb9b7e4a68c7b3e27975d9a1a5f0
7
- data.tar.gz: 59ca4da7a641b8c66f8de5452c647cf56301a37ce5a62e0b0de4a02165d90749f594c5ad6b139fef361f18e7a2dd63f0bb2b2e1eea13590d5a77a99bcdd0e3e5
6
+ metadata.gz: f5437965558d61fbb534ac2cef46c51b70f9a1ba08550dc3aece6b474bb3501b7fbcd53a386f999f5efbe776c0e41fb56bef632c3a5c238687bd516fb6503a46
7
+ data.tar.gz: bf03d88d2fa2a4fab03522f1b14321ddf35076ae3781a4e545c0f683d25b5d1c5d03f25364fa74deb2c350f5becb9ba0b1c4cabf452b9a602cbb41b93cee640d
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- graphql-result_cache (0.1.0)
4
+ graphql-result_cache (0.1.2)
5
5
  graphql (~> 1.9)
6
6
 
7
7
  GEM
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
- @value[context.query] << { path: context.path, key: key, result: cached ? cache.read(key) : nil }
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
- deep_merge! result.to_h, 'data' => config[:path].reverse.inject(config[:result]) { |a, n| {n => a} }
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
- # for cacheable field, change type to be nullable
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
- cached = ctx[:result_cache].add context: ctx, key: cache_key.to_s
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
@@ -21,7 +21,7 @@ module GraphQL
21
21
  private
22
22
 
23
23
  def path_clause
24
- @ctx.path.join('/')
24
+ @ctx.path.join('.')
25
25
  end
26
26
 
27
27
  def args_clause
@@ -1,5 +1,5 @@
1
1
  module GraphQL
2
2
  module ResultCache
3
- VERSION = '0.1.1'
3
+ VERSION = '0.1.2'
4
4
  end
5
5
  end
@@ -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.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-07-17 00:00:00.000000000 Z
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