Skip to content

Instantly share code, notes, and snippets.

@DmitryTsepelev
Last active September 22, 2019 09:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DmitryTsepelev/065bb6bc796898f5745c4209d1b4bb21 to your computer and use it in GitHub Desktop.
Save DmitryTsepelev/065bb6bc796898f5745c4209d1b4bb21 to your computer and use it in GitHub Desktop.
GraphQL field extensions
require "bundler/inline"
gemfile do
source "https://rubygems.org"
gem "graphql"
end
class BaseObject < GraphQL::Schema::Object
end
class QueryType < BaseObject
field :cached_val, String, null: false
def cached_val
"I'm cached at #{Time.now}"
end
end
class GraphqlSchema < GraphQL::Schema
query QueryType
end
query = <<-gql
query {
cachedVal
}
gql
puts GraphqlSchema.execute(query).dig("data", "cachedVal")
sleep 3
puts GraphqlSchema.execute(query).dig("data", "cachedVal")
require "bundler/inline"
gemfile do
source "https://rubygems.org"
gem "graphql"
end
class BaseObject < GraphQL::Schema::Object
end
class CacheExtension < GraphQL::Schema::FieldExtension
def resolve(object:, arguments:, **rest)
key = cache_key(object, arguments)
store[key] ||= yield(object, arguments)
end
private
def store
Thread.current[:field_cache] ||= {}
end
def cache_key(object, arguments)
"#{object.class.name}-#{@field}-#{arguments.hash}"
end
end
class QueryType < BaseObject
field :cached_val, String, null: false, extensions: [CacheExtension]
def cached_val
"I'm cached at #{Time.now}"
end
end
class GraphqlSchema < GraphQL::Schema
query QueryType
end
query = <<-gql
query {
cachedVal
}
gql
puts GraphqlSchema.execute(query).dig("data", "cachedVal")
sleep 3
puts GraphqlSchema.execute(query).dig("data", "cachedVal")
require "bundler/inline"
gemfile do
source "https://rubygems.org"
gem "graphql"
end
class BaseObject < GraphQL::Schema::Object
field_class.prepend(Module.new do
def initialize(*args, **kwargs, &block)
if kwargs.delete(:cached)
kwargs[:extensions] ||= [] << CacheExtension
end
super
end
end)
end
class CacheExtension < GraphQL::Schema::FieldExtension
def resolve(object:, arguments:, **rest)
key = cache_key(object, arguments)
store[key] ||= yield(object, arguments)
end
private
def store
Thread.current[:field_cache] ||= {}
end
def cache_key(object, arguments)
"#{object.class.name}-#{@field}-#{arguments.hash}"
end
end
class QueryType < BaseObject
field :cached_val, String, null: false, cached: true
def cached_val
"I'm cached at #{Time.now}"
end
end
class GraphqlSchema < GraphQL::Schema
query QueryType
end
query = <<-gql
query {
cachedVal
}
gql
puts GraphqlSchema.execute(query).dig("data", "cachedVal")
sleep 3
puts GraphqlSchema.execute(query).dig("data", "cachedVal")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment