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
         |