graphql-result_cache 0.1.8 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c6f11b53f28b2c9c5bd70a0f985b106e6a8b530d1a236122db13cacd3f92229c
4
- data.tar.gz: 37dea5a5328235136a09cb983f800b4cd91fa227fc20f2501d3a766ec7c00508
3
+ metadata.gz: 535b29453885101a889e6228ded5fd20a83dd6e09f104fc3e9f369e1324b2d28
4
+ data.tar.gz: e8bad278755e2357bd12aa64ecf3e6078f307ede91625e21ed6794f5e6731144
5
5
  SHA512:
6
- metadata.gz: 64120b5bfb3d1e5ca80d3fb01d01a158cd441eaeda3640da504080edb04070669b9c0920ab2c08732f9dc6bc07162c8916c5c5361cac514b06c44fd5a781cd9e
7
- data.tar.gz: 4080d919a8b2acc3b6dff84cace90799f13159705d2bda7aff567586bdaea982a8b5dcabb161f9b3e26d959119ce481a8821a1e830d35ec3e2508ac7714df63f
6
+ metadata.gz: 329163b7405a290722f3e594548eaebf459dbfd01d0a5727030b6272043088dc99b2a3acf455b9f40fa4174084b4f37bb17db3da767862ef457ef7a6d8fe2592
7
+ data.tar.gz: 34dcf33d3e285be6f08c94eba94ea10845f7204eb3fc6247744e16c0377c6ff6f13d75c83f79d17bc247094fc1cf468492a21432f1c72e246e82dc660165d6cd
data/Gemfile.lock CHANGED
@@ -1,37 +1,37 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- graphql-result_cache (0.1.8)
5
- graphql (~> 1.9)
4
+ graphql-result_cache (1.0.0)
5
+ graphql (~> 1.10)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- diff-lcs (1.3)
11
- graphql (1.9.12)
12
- rake (13.0.1)
13
- rspec (3.8.0)
14
- rspec-core (~> 3.8.0)
15
- rspec-expectations (~> 3.8.0)
16
- rspec-mocks (~> 3.8.0)
17
- rspec-core (3.8.2)
18
- rspec-support (~> 3.8.0)
19
- rspec-expectations (3.8.4)
10
+ diff-lcs (1.4.4)
11
+ graphql (1.12.20)
12
+ rake (12.3.3)
13
+ rspec (3.10.0)
14
+ rspec-core (~> 3.10.0)
15
+ rspec-expectations (~> 3.10.0)
16
+ rspec-mocks (~> 3.10.0)
17
+ rspec-core (3.10.1)
18
+ rspec-support (~> 3.10.0)
19
+ rspec-expectations (3.10.1)
20
20
  diff-lcs (>= 1.2.0, < 2.0)
21
- rspec-support (~> 3.8.0)
22
- rspec-mocks (3.8.1)
21
+ rspec-support (~> 3.10.0)
22
+ rspec-mocks (3.10.2)
23
23
  diff-lcs (>= 1.2.0, < 2.0)
24
- rspec-support (~> 3.8.0)
25
- rspec-support (3.8.2)
24
+ rspec-support (~> 3.10.0)
25
+ rspec-support (3.10.3)
26
26
 
27
27
  PLATFORMS
28
28
  ruby
29
29
 
30
30
  DEPENDENCIES
31
- bundler (>= 2.2.10)
31
+ bundler (~> 2.2, >= 2.2.10)
32
32
  graphql-result_cache!
33
- rake (>= 12.3.3)
34
- rspec (~> 3.0)
33
+ rake (~> 12.3, >= 12.3.3)
34
+ rspec (~> 3.10)
35
35
 
36
36
  BUNDLED WITH
37
37
  2.2.31
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  This gem is to cache the json result, instead of resolved object.
4
4
 
5
+ If you are using `graphql < 1.10.0` or without `GraphQL::Execution::Interpreter`, please [read this](https://github.com/saharaying/graphql-result_cache/wiki/GraphQL::ResultCache-(v0.1.x)).
6
+
5
7
  ## Installation
6
8
 
7
9
  Add this line to your application's Gemfile:
@@ -21,65 +23,57 @@ Or install it yourself as:
21
23
  ## Usage
22
24
 
23
25
  1. Use `GraphQL::ResultCache` as a plugin in your schema.
24
-
26
+
25
27
  ```ruby
26
28
  class MySchema < GraphQL::Schema
29
+ # Default value for graphql v1.12.x
30
+ use GraphQL::Execution::Interpreter
31
+ use GraphQL::Analysis::AST
32
+
33
+ introspection GraphQL::ResultCache::Introspection
34
+
27
35
  mutation Types::MutationType
28
36
  query Types::QueryType
29
-
37
+
30
38
  use GraphQL::ResultCache
31
39
  end
32
40
  ```
33
41
 
34
- 2. Add the custom field class to accept `result_cache` metadata.
42
+ 2. Add the custom field class to accept `result_cache` definition.
35
43
 
36
44
  ```ruby
37
45
  module Types
38
46
  class BaseObject < GraphQL::Schema::Object
39
- field_class GraphQL::ResultCache::Field
47
+ field_class GraphQL::ResultCache::Schema::Field
40
48
  end
41
49
  end
42
50
  ```
43
51
 
44
- 3. Config the fields which need to be cached with `result_cache` definition.
52
+ 3. Config the fields which need to be cached.
45
53
 
46
54
  ```ruby
47
55
  field :theme, Types::ThemeType, null: false, result_cache: true
48
56
  ```
49
57
 
50
- 4. Wrap query result with `GraphQL::ResultCache::Result`.
51
-
52
- ```ruby
53
- class GraphqlController < ApplicationController
54
- def execute
55
- # ...
56
- result = if params[:_json]
57
- multiple_execute(params[:_json], context: context)
58
- else
59
- execute_query(context: context)
60
- end
61
- render json: GraphQL::ResultCache::Result.new(result)
62
- end
63
- end
64
- ```
65
-
66
58
  ## Result Cache Customization
67
59
 
68
60
  ### Cache condition
69
61
 
62
+ The `if` condition can be either a Symbol or a Proc.
63
+
70
64
  ```ruby
71
65
  field :theme, Types::ThemeType, null: false, result_cache: { if: :published? }
72
66
  ```
73
- The `if` condition can be either a Symbol or a Proc.
74
67
 
75
68
  ### Customized cache key
76
69
 
77
- By default, `GraphQL::ResultCache` will generate a cache key combining the field path, arguments and object.
70
+ By default, `GraphQL::ResultCache` will generate a cache key combining the field path, arguments and object.
78
71
  But you can customize the object clause by specify the `key` option.
79
72
 
80
73
  ```ruby
81
74
  field :theme, Types::ThemeType, null: false, result_cache: { key: :theme_cache_key }
82
75
  ```
76
+
83
77
  The `key` can be either a Symbol or a Proc.
84
78
 
85
79
  ### Callback after cached result applied
@@ -114,7 +108,7 @@ end
114
108
  When using with introspection, you need to assign custom introspection to avoid getting the nullable type for a non-null type.
115
109
  ```ruby
116
110
  class MySchema < GraphQL::Schema
117
- introspection ::GraphQL::ResultCache::Introspection
111
+ introspection GraphQL::ResultCache::Introspection
118
112
  end
119
113
  ```
120
114
 
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ['saharaying@gmail.com']
11
11
 
12
12
  spec.summary = 'A result caching plugin for graphql-ruby'
13
- spec.description = 'A result caching plugin for graphql-ruby'
13
+ spec.description = 'This gem is to cache the json result, instead of resolved object.'
14
14
  spec.homepage = 'https://github.com/saharaying/graphql-result_cache'
15
15
  spec.license = 'MIT'
16
16
 
@@ -19,11 +19,11 @@ Gem::Specification.new do |spec|
19
19
  end
20
20
  spec.require_paths = ['lib']
21
21
 
22
- spec.add_development_dependency 'bundler', '>= 2.2.10'
23
- spec.add_development_dependency 'rake', '>= 12.3.3'
24
- spec.add_development_dependency 'rspec', '~> 3.0'
22
+ spec.add_development_dependency 'bundler', '~> 2.2', '>= 2.2.10'
23
+ spec.add_development_dependency 'rake', '~> 12.3', '>= 12.3.3'
24
+ spec.add_development_dependency 'rspec', '~> 3.10'
25
25
 
26
- spec.add_dependency 'graphql', '~> 1.9'
26
+ spec.add_dependency 'graphql', '~> 1.10'
27
27
 
28
28
  # graphql v1.9 requires ruby >= 2.2.0
29
29
  spec.required_ruby_version = '>= 2.2.0'
@@ -1,21 +1,27 @@
1
1
  module GraphQL
2
2
  module ResultCache
3
3
  class Callback
4
- def initialize obj:, args:, ctx:, value:
4
+ def initialize(obj:, args:, ctx:, value:)
5
5
  @obj = obj
6
6
  @args = args
7
7
  @ctx = ctx
8
8
  @value = value
9
9
  end
10
10
 
11
- def call result_hash
11
+ def call(result_hash)
12
12
  case @value
13
13
  when Symbol
14
14
  @obj.public_send(@value, result_hash)
15
15
  when Proc
16
16
  @value.call(result_hash, @obj, @args, @ctx)
17
17
  end
18
- ::GraphQL::ResultCache.logger && ::GraphQL::ResultCache.logger.debug("GraphQL result cache callback called for #{@ctx.path.join('.')}")
18
+ ::GraphQL::ResultCache.logger && ::GraphQL::ResultCache.logger.debug("GraphQL result cache callback called for #{ctx_path}")
19
+ end
20
+
21
+ private
22
+
23
+ def ctx_path
24
+ @ctx.namespace(:interpreter)[:current_path].join('.')
19
25
  end
20
26
  end
21
27
  end
@@ -8,16 +8,16 @@ module GraphQL
8
8
  @value = {}
9
9
  end
10
10
 
11
- def add context:, key:, after_process: nil
12
- @value[context.query] ||= []
11
+ def add query:, path:, key:, after_process: nil
12
+ @value[query] ||= []
13
13
  cached = cache.exist? key
14
14
  logger && logger.info("GraphQL result cache key #{cached ? 'hit' : 'miss'}: #{key}")
15
- config_value = { path: context.path, key: key }
15
+ config_value = { path: path, key: key }
16
16
  if cached
17
17
  config_value[:result] = cache.read(key)
18
18
  config_value[:after_process] = after_process if after_process
19
19
  end
20
- @value[context.query] << config_value
20
+ @value[query] << config_value
21
21
  cached
22
22
  end
23
23
 
@@ -4,7 +4,8 @@ module GraphQL
4
4
  class FieldType < ::GraphQL::Introspection::FieldType
5
5
 
6
6
  def type
7
- @object.metadata[:original_non_null] && !@object.type.non_null? ? @object.type.to_non_null_type : @object.type
7
+ return @object.type unless @object.respond_to?(:original_return_type_not_null)
8
+ @object.original_return_type_not_null && !@object.type.non_null? ? @object.type.to_non_null_type : @object.type
8
9
  end
9
10
 
10
11
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GraphQL
2
4
  module ResultCache
3
5
  class Key
4
- def initialize obj:, args:, ctx:, key: nil
6
+ def initialize(obj:, args:, ctx: nil, key: nil)
5
7
  @obj = obj
6
8
  @args = args
7
9
  @ctx = ctx
@@ -21,7 +23,7 @@ module GraphQL
21
23
  private
22
24
 
23
25
  def path_clause
24
- @ctx.path.join('.')
26
+ @ctx.namespace(:interpreter)[:current_path].join('.') unless @ctx.nil?
25
27
  end
26
28
 
27
29
  def args_clause
@@ -53,7 +55,6 @@ module GraphQL
53
55
  return object.id if object.respond_to?(:id)
54
56
  object.object_id
55
57
  end
56
-
57
58
  end
58
59
  end
59
- end
60
+ end
@@ -1,27 +1,24 @@
1
1
  module GraphQL
2
2
  module ResultCache
3
3
  class Result
4
- extend Forwardable
5
-
6
- attr_reader :value
7
-
8
- def_delegators :@value, :to_json, :as_json
9
-
10
4
  def initialize query_result
11
5
  @_result = query_result
12
- @value = process_with_result_cache
6
+ end
7
+
8
+ def process!
9
+ process_with_result_cache
13
10
  end
14
11
 
15
12
  private
16
13
 
17
14
  def process_with_result_cache
18
15
  return process_each(@_result) unless @_result.is_a?(Array)
19
- @_result.map { |result| process_each(result) }
16
+ @_result.each { |result| process_each(result) }
20
17
  end
21
18
 
22
19
  def process_each result
23
20
  result_cache_config = result.query.context[:result_cache]
24
- blank?(result_cache_config) ? result : result_cache_config.process(result)
21
+ result_cache_config.process(result) unless blank?(result_cache_config)
25
22
  end
26
23
 
27
24
  def blank? obj
@@ -0,0 +1,19 @@
1
+ module GraphQL
2
+ module ResultCache
3
+ module Schema
4
+ class Field < ::GraphQL::Schema::Field
5
+ attr_reader :original_return_type_not_null
6
+
7
+ def initialize(*args, result_cache: nil, **kwargs, &block)
8
+ super(*args, **kwargs, &block)
9
+ return unless result_cache
10
+ unless @return_type_null
11
+ @original_return_type_not_null = true
12
+ @return_type_null = true
13
+ end
14
+ extension FieldExtension, result_cache
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql/result_cache/condition'
4
+ require 'graphql/result_cache/context_config'
5
+ require 'graphql/result_cache/key'
6
+ require 'graphql/result_cache/callback'
7
+
8
+ module GraphQL
9
+ module ResultCache
10
+ module Schema
11
+ class FieldExtension < GraphQL::Schema::FieldExtension
12
+ def resolve(object:, arguments:, context:)
13
+ cache_config = options.respond_to?(:to_h) ? options.to_h : {}
14
+
15
+ if Condition.new(cache_config, obj: object, args: arguments, ctx: context).true?
16
+ context[:result_cache] ||= ContextConfig.new
17
+ cached = add_to_context_result_cache(context, object, arguments, cache_config)
18
+ end
19
+
20
+ yield(object, arguments) unless cached
21
+ end
22
+
23
+ private
24
+
25
+ def add_to_context_result_cache(context, object, arguments, cache_config)
26
+ cache_key = key(object, arguments, context, cache_config)
27
+ after_process = after_process(object, arguments, context, cache_config)
28
+ context[:result_cache].add(
29
+ query: context.query,
30
+ path: context.namespace(:interpreter)[:current_path],
31
+ key: cache_key.to_s,
32
+ after_process: after_process
33
+ )
34
+ end
35
+
36
+ def key(object, arguments, context, config)
37
+ Key.new(
38
+ obj: object,
39
+ args: arguments,
40
+ ctx: context,
41
+ key: config[:key]
42
+ )
43
+ end
44
+
45
+ def after_process(object, arguments, context, config)
46
+ return unless config[:after_process]
47
+
48
+ Callback.new(
49
+ obj: object,
50
+ args: arguments,
51
+ ctx: context,
52
+ value: config[:after_process]
53
+ )
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,15 @@
1
+ module GraphQL
2
+ module ResultCache
3
+ module Schema
4
+ module QueryInstrument
5
+ module_function
6
+
7
+ def before_query(_query) end
8
+
9
+ def after_query(query)
10
+ GraphQL::ResultCache::Result.new(query.result).process!
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,5 +1,5 @@
1
1
  module GraphQL
2
2
  module ResultCache
3
- VERSION = '0.1.8'
3
+ VERSION = '1.0.0'
4
4
  end
5
5
  end
@@ -1,8 +1,9 @@
1
1
  require 'graphql'
2
2
  require 'graphql/result_cache/version'
3
- require 'graphql/result_cache/field'
4
3
  require 'graphql/result_cache/result'
5
- require 'graphql/result_cache/field_instrument'
4
+ require 'graphql/result_cache/schema/field'
5
+ require 'graphql/result_cache/schema/field_extension'
6
+ require 'graphql/result_cache/schema/query_instrument'
6
7
  require 'graphql/result_cache/introspection'
7
8
 
8
9
  module GraphQL
@@ -31,15 +32,16 @@ module GraphQL
31
32
  def configure
32
33
  yield self
33
34
  end
35
+
36
+ def use(schema_def)
37
+ return schema_def.instrument(:query, Schema::QueryInstrument) if schema_def.interpreter?
38
+ raise 'Please use the graphql gem version >= 1.10 with GraphQL::Execution::Interpreter'
39
+ end
34
40
  end
35
41
 
36
42
  # Default configuration
37
- @expires_in = 3600 # 1.hour
43
+ @expires_in = 3600 # 1.hour
38
44
  @namespace = 'GraphQL:Result'
39
-
40
- def self.use(schema_def, options: {})
41
- schema_def.instrument(:field, ::GraphQL::ResultCache::FieldInstrument.new)
42
- end
43
45
  end
44
46
  end
45
47
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql-result_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ying Fu
@@ -14,6 +14,9 @@ dependencies:
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.2'
17
20
  - - ">="
18
21
  - !ruby/object:Gem::Version
19
22
  version: 2.2.10
@@ -21,6 +24,9 @@ dependencies:
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.2'
24
30
  - - ">="
25
31
  - !ruby/object:Gem::Version
26
32
  version: 2.2.10
@@ -28,6 +34,9 @@ dependencies:
28
34
  name: rake
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '12.3'
31
40
  - - ">="
32
41
  - !ruby/object:Gem::Version
33
42
  version: 12.3.3
@@ -35,6 +44,9 @@ dependencies:
35
44
  prerelease: false
36
45
  version_requirements: !ruby/object:Gem::Requirement
37
46
  requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '12.3'
38
50
  - - ">="
39
51
  - !ruby/object:Gem::Version
40
52
  version: 12.3.3
@@ -44,36 +56,35 @@ dependencies:
44
56
  requirements:
45
57
  - - "~>"
46
58
  - !ruby/object:Gem::Version
47
- version: '3.0'
59
+ version: '3.10'
48
60
  type: :development
49
61
  prerelease: false
50
62
  version_requirements: !ruby/object:Gem::Requirement
51
63
  requirements:
52
64
  - - "~>"
53
65
  - !ruby/object:Gem::Version
54
- version: '3.0'
66
+ version: '3.10'
55
67
  - !ruby/object:Gem::Dependency
56
68
  name: graphql
57
69
  requirement: !ruby/object:Gem::Requirement
58
70
  requirements:
59
71
  - - "~>"
60
72
  - !ruby/object:Gem::Version
61
- version: '1.9'
73
+ version: '1.10'
62
74
  type: :runtime
63
75
  prerelease: false
64
76
  version_requirements: !ruby/object:Gem::Requirement
65
77
  requirements:
66
78
  - - "~>"
67
79
  - !ruby/object:Gem::Version
68
- version: '1.9'
69
- description: A result caching plugin for graphql-ruby
80
+ version: '1.10'
81
+ description: This gem is to cache the json result, instead of resolved object.
70
82
  email:
71
83
  - saharaying@gmail.com
72
84
  executables: []
73
85
  extensions: []
74
86
  extra_rdoc_files: []
75
87
  files:
76
- - ".github/workflows/gem-push.yml"
77
88
  - ".github/workflows/ruby.yml"
78
89
  - ".gitignore"
79
90
  - ".rspec"
@@ -90,13 +101,14 @@ files:
90
101
  - lib/graphql/result_cache/callback.rb
91
102
  - lib/graphql/result_cache/condition.rb
92
103
  - lib/graphql/result_cache/context_config.rb
93
- - lib/graphql/result_cache/field.rb
94
- - lib/graphql/result_cache/field_instrument.rb
95
104
  - lib/graphql/result_cache/introspection.rb
96
105
  - lib/graphql/result_cache/introspection/field_type.rb
97
106
  - lib/graphql/result_cache/key.rb
98
107
  - lib/graphql/result_cache/rails.rb
99
108
  - lib/graphql/result_cache/result.rb
109
+ - lib/graphql/result_cache/schema/field.rb
110
+ - lib/graphql/result_cache/schema/field_extension.rb
111
+ - lib/graphql/result_cache/schema/query_instrument.rb
100
112
  - lib/graphql/result_cache/version.rb
101
113
  homepage: https://github.com/saharaying/graphql-result_cache
102
114
  licenses:
@@ -1,45 +0,0 @@
1
- name: Ruby Gem
2
-
3
- on:
4
- push:
5
- branches: [ master ]
6
- pull_request:
7
- branches: [ master ]
8
-
9
- jobs:
10
- build:
11
- name: Build + Publish
12
- runs-on: ubuntu-latest
13
- permissions:
14
- contents: read
15
- packages: write
16
-
17
- steps:
18
- - uses: actions/checkout@v2
19
- - name: Set up Ruby 2.6
20
- uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
21
- with:
22
- ruby-version: 2.6.6
23
-
24
- - name: Publish to GPR
25
- run: |
26
- mkdir -p $HOME/.gem
27
- touch $HOME/.gem/credentials
28
- chmod 0600 $HOME/.gem/credentials
29
- printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
30
- gem build *.gemspec
31
- gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
32
- env:
33
- GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
34
- OWNER: ${{ github.repository_owner }}
35
-
36
- - name: Publish to RubyGems
37
- run: |
38
- mkdir -p $HOME/.gem
39
- touch $HOME/.gem/credentials
40
- chmod 0600 $HOME/.gem/credentials
41
- printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
42
- gem build *.gemspec
43
- gem push *.gem
44
- env:
45
- GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
@@ -1,17 +0,0 @@
1
- module GraphQL
2
- module ResultCache
3
- class Field < ::GraphQL::Schema::Field
4
- def initialize(*args, result_cache: nil, **kwargs, &block)
5
- @result_cache_config = result_cache
6
- super(*args, **kwargs, &block)
7
- end
8
-
9
- def to_graphql
10
- field_defn = super # Returns a GraphQL::Field
11
- field_defn.metadata[:result_cache] = @result_cache_config
12
- field_defn.metadata[:original_non_null] = true if @result_cache_config && field_defn.type.non_null?
13
- field_defn
14
- end
15
- end
16
- end
17
- end
@@ -1,37 +0,0 @@
1
- require 'graphql/result_cache/condition'
2
- require 'graphql/result_cache/context_config'
3
- require 'graphql/result_cache/key'
4
- require 'graphql/result_cache/callback'
5
-
6
- module GraphQL
7
- module ResultCache
8
- class FieldInstrument
9
- def instrument _type, field
10
- return field unless field.metadata[:result_cache]
11
-
12
- cached_resolve_proc = cached_resolve(field)
13
- field.redefine do
14
- resolve(cached_resolve_proc)
15
- type(field.type.of_type) if field.type.non_null?
16
- end
17
- end
18
-
19
- private
20
-
21
- def cached_resolve field
22
- old_resolve_proc = field.resolve_proc
23
- cache_config = field.metadata[:result_cache]
24
- cache_config = {} unless cache_config.is_a?(Hash)
25
- lambda do |obj, args, ctx|
26
- if Condition.new(cache_config, obj: obj, args: args, ctx: ctx).true?
27
- ctx[:result_cache] ||= ContextConfig.new
28
- cache_key = Key.new(obj: obj, args: args, ctx: ctx, key: cache_config[:key])
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
31
- end
32
- old_resolve_proc.call(obj, args, ctx) unless cached
33
- end
34
- end
35
- end
36
- end
37
- end