dmitrytsepelev / graphql-ruby-fragment_cache Goto Github PK
View Code? Open in Web Editor NEWgraphql-ruby plugin for caching parts of the response
License: MIT License
graphql-ruby plugin for caching parts of the response
License: MIT License
When running this with graphql 2.2.7, it shows a deprecation warning:
Schema.instrument is deprecated, use `trace_with` instead: https://graphql-ruby.org/queries/tracing.html"
(From `MyAppSchema.instrument(query, GraphQL::FragmentCache::Schema::Instrumentation)` at /Users/myuser/.gem/ruby/3.2.2/gems/graphql-fragment_cache-1.19.0/lib/graphql/fragment_cache.rb:35:in `use')
The 2.0.18 update to graphql-ruby adds a breaking change to tracers that affects this gem.
Tracing: "execute_field" events on fields defined on interface types will now receive the interface type as data[:owner] instead of the current object type. To get the old behavior, use data[:object].class instead. #4292
A change would likely need to be made in this file: lib/graphql/fragment_cache/schema/tracer.rb
This is causing the below error when attempting to use the gql schema:
Can't add tracer after configuring a `trace_class`, use GraphQL::Tracing::LegacyTrace to merge legacy tracers into a trace class instead.
I'll attempt to make a PR to fix this but am not very familiar with the internal working of this gem or graphql-ruby.
class PostType < GraphQL::Schema::Object
field :id, ID, null: false
field :title, String, null: false, cache_fragment: { ex: 2.days }
end
class QueryType < GraphQL::Schema::Object
field :post, PostType, null: true do
argument :id, ID, required: true
end
def post(id:)
cache_fragment(ex: 2.days) { Post.find(id) }
end
end
Does this gem support cache_versioning=true?
config.active_record.cache_versioning = true
rails/rails#29092
https://bigbinary.com/blog/rails-adds-support-for-recyclable-cache-keys
class QueryType < GraphQL::Schema::Object
field :post, PostType, null: true do
argument :id, ID, required: true
end
def post(id:)
cache_fragment(context_cache_key: context[:current_user_id]) { Post.find(id) }
end
end
Hi all. Could somebody implement keys method in MemoryStore instance? It's gonna be helpful to get all exists keys and filter by mask and to delete not relevant by hand. Currently I can use GraphQL::FragmentCache.cache_store.instance_variable_get(:@storage).keys
. Thanks.
Hello, I have this issue with context
. It throws and error of trying to access a method on a hash.
module Types::Object
class UserType < BaseObject
field :last_name, String, null: false, cache_fragment: true
end
end
Inside gem, it calls cache_fragment
method which is building an instance of Fragment. And it's failing there:
# lib/graphql/fragment_cache/fragment.rb
def interpreter_context
context.namespace(:interpreter)
end
But context is a hash here, so I'm getting
[1] pry(#<GraphQL::Execution::Errors>)> err
=> #<NoMethodError: undefined method `namespace' for #<Hash:0x00007f2bc3d9f8c8>>
Basically, it's exactly that context
hash that I build in GraphqlController execute
method, common setup:
class GraphqlController < ActionController::API
def execute
context = {
current_user: current_user
}
render json: AppSchema.execute(
params[:query],
variables: variables,
context: context,
operation_name: params[:operation_name]
)
end
end
Rails 5.2.4
ruby 2.6.5
graphql 1.11.1
graphql-fragment_cache 1.0.1
Hello,
I'm running into the exact same error that @CestarBe had in #26, namely that when the context
object is being referenced by this library, it is just a Hash
and not a GraphQL::Query::Context
, therefore it does not have a method called namespace
.
#<NoMethodError: undefined method `namespace' for #<Hash:0x00007f2bc3d9f8c8>>
I attempted to debug this by printing the class of context
inside my QueryType
object and it says that even there the context
is just a Hash
.
My query object looks something like this:
class QueryType < Types::BaseObject
field get_post, Post
def post
print(context.class) # <--- THIS IS A HASH
PostResolver.new.call(object, args, context)
end
end
Anyone have any ideas how this could be happening? My GraphqlController
and Schema
setups look just like the examples in the documentation.
We have a use case in Rails where we need to specify a cache key (from a Rails ActiveRecord::Relation
), but it's not the return value - the relation is processed, which takes quite a long time. Unfortunately, specifying query_cache_key
removes the path and the selections keys, which we also need. There does not seem to be a way to specify "extra key". Something like this:
cache_fragment(object_cache_key: where_class.cache_key_with_version) { where_class.do_something }
And the resulting cache key would be:
52355f50328bf0e765dd0cfcc89f11a5f503a082/special_models/query-f99c1b73939dae707295bf67deadbeef-1-20210212224532037173
(or it would be hashed)
I'm thinking it would be like this:
class CacheKeyBuilder
def object_key(obj)
@options.fetch(:object_cache_key) { obj._graphql_cache_key }
end
end
Do you think this is a reasonable feature?
Issue:
Getting an undefined method error for versions of GraphQL Ruby greater than v1.12.10.
undefined method `final_value' for #<GraphQL::Execution::Interpreter::Runtime:0x00007f223dddedf0>
Did you mean? final_result
/usr/local/bundle/gems/graphql-fragment_cache-0.1.4/lib/graphql/fragment_cache/cacher.rb:13:in `call'
/usr/local/bundle/gems/graphql-fragment_cache-0.1.4/lib/graphql/fragment_cache/instrumentation.rb:17:in `after_query'
I fixed this by downgrading to v1.12.10.
Maybe this method got renamed to final_result
in the later versions?
See API docs here:
https://graphql-ruby.org/api-doc/1.12.10/GraphQL/Execution/Interpreter/Runtime.html#final_value-instance_method
vs
https://graphql-ruby.org/api-doc/1.12.14/GraphQL/Execution/Interpreter/Runtime.html#final_result-instance_method
Love the package otherwise. Keep up the great work ๐
I have the following quick and dirty monkey patch:
# Monkey patch to make the cache key more human-readable for easier debugging
module GraphQL
module FragmentCache
class CacheKeyBuilder
module MonkeyPatch
def implicit_cache_key
full_cache_key = query_cache_key
cache_key_first_part = full_cache_key.split('(').first.split('[').first.tr('/', '-')
hex_cache_key = Digest::SHA1.hexdigest(full_cache_key)
"#{cache_key_first_part}/#{hex_cache_key}"
end
def object_cache_key
super&.tr('/', '-')
end
end
prepend MonkeyPatch
end
end
end
This makes cache keys look like this:
[41] pry(main)> $redis.keys('graphql*').sort
[
[ 0] "graphql/post/766b6ccc10ab9495379351ee8beafea5c6007503/1595-mycorp",
[ 1] "graphql/currentTenant-activities/8fb06e96554aadb59acc95055d94ac32e35ad383/1595-mycorp",
[ 2] "graphql/currentTenant-posts/f328972b1d41071057c1e9b2ba2942376ead0def/posts-query-5f6b140cd0b110df8830cb806289afae-6-20220927164337385299-mycorp",
[ 3] "graphql/currentTenant-orgs/8cd8ca77d3d80ce63a3c71f3458e13f871976742/orgs-query-a1cd705421842de6905cfb2f6c372fc8-1-20220908170650370442-mycorp",
[ 4] "graphql/currentTenant-orgs/9d43405f9a04e5a7007c7a5b23e9a83025195513/orgs-query-a1cd705421842de6905cfb2f6c372fc8-1-20220908170650370442-mycorp",
[ 5] "graphql/currentUser-companies-0-plans/636959b06ed3087a042294887cf024825324b17d/companies-28712-20221017002729396154-mycorp",
[ 6] "graphql/currentUser-companies/3ce35c987a1634135bfdde439535f8d0d80c70ab/users-234196-20221017141421202813-mycorp",
[ 7] "graphql/tool/136783447b0def9ee3eeffdee6e7d0724b25729d",
[ 8] "graphql/tool/18ab5818aea282fc778f11f263862d7420491eab/tools-989-20221018005011056666-mycorp",
[ 9] "graphql/tool/476a0e82181713884b6fc38efd8668cb55b35e16/companies-1281-20221018005011252828-mycorp",
[10] "graphql/tool/59965cf1a9b31ce7dae6722c5a786a66658c865e/tools-989-20221018005011056666-mycorp"
]
What is nice is that I now get a pretty good idea of what the key is about: the query fingerprint is still there in the middle, but it is prefixed with the query path in plain text, and suffixed with the object cache key in plain text.
This has proved very valuable:
$redis.keys('*activities*')
) or for a particular customer ($redis.keys('*activities*mycorp')
)Rails.cache.delete_matched('*posts*')
) without having to use the nuclear Rails.cache.clear
optionOn the flip side the keys are longer, but in practice it hasn't been a problem in my app. I should also mention that I am using redis as my cache store, and since the max key size is 512 MB, I probably won't ever have the issue of keys being too long.
I feel like an option to make keys more human-readable (or maybe even by default) would be helpful. But maybe my needs are too specific.
Do you this is somewhat useful? If so we could make a PR.
I have problem with AR collections.
When I try to read a collection, I get an error related to the cache key
rails 6.0.3.1
graphql-fragment_cache 0.1.5
graphql 1.10.10
ruby 2.7.1
module Types
class QueryType < Types::BaseObject
field :exercise, Types::ExerciseType, resolver: Queries::ExerciseQuery
field :exercises, [Types::ExerciseType], resolver: Queries::ExercisesQuery, cache_fragment: true
end
end
module Types
class ExerciseType < Types::BaseObject
field :id, ID, null: false
field :course_id, ID, null: false, cache_fragment: true
end
end
And resolvers
module Queries
class ExerciseResolver < Queries::BaseQuery
argument :id, ID, required: true
type Types::ExerciseType, null: true
def resolve(id:)
Exercise.find(id)
end
end
end
module Queries
class ExercisesResolver < Queries::BaseQuery
type [Types::ExerciseType], null: true
def resolve(id:)
Exercise.all
end
end
end
and when I trying to get a collection if any of fields Types::ExerciseType uses caching, then I get an error
rails_1 | [9ecf2522-ed52-4d25-b5b1-62631be97a01] Failed to look ahead the field: 0
rails_1 | [9ecf2522-ed52-4d25-b5b1-62631be97a01] /usr/local/bundle/gems/graphql-fragment_cache-0.1.5/lib/graphql/fragment_cache/cache_key_builder.rb:137:in `block in path_cache_key'
rails_1 | /usr/local/bundle/gems/graphql-fragment_cache-0.1.5/lib/graphql/fragment_cache/cache_key_builder.rb:135:in `map'
rails_1 | /usr/local/bundle/gems/graphql-fragment_cache-0.1.5/lib/graphql/fragment_cache/cache_key_builder.rb:135:in `path_cache_key'
rails_1 | /usr/local/bundle/gems/graphql-fragment_cache-0.1.5/lib/graphql/fragment_cache/cache_key_builder.rb:122:in `query_cache_key'
rails_1 | /usr/local/bundle/gems/graphql-fragment_cache-0.1.5/lib/graphql/fragment_cache/cache_key_builder.rb:109:in `build'
rails_1 | /usr/local/bundle/gems/graphql-fragment_cache-0.1.5/lib/graphql/fragment_cache/cache_key_builder.rb:94:in `call'
rails_1 | /usr/local/bundle/gems/graphql-fragment_cache-0.1.5/lib/graphql/fragment_cache/fragment.rb:31:in `cache_key'
rails_1 | /usr/local/bundle/gems/graphql-fragment_cache-0.1.5/lib/graphql/fragment_cache/fragment.rb:20:in `read'
rails_1 | /usr/local/bundle/gems/graphql-fragment_cache-0.1.5/lib/graphql/fragment_cache/object_helpers.rb:26:in `cache_fragment'
rails_1 | /usr/local/bundle/gems/graphql-fragment_cache-0.1.5/lib/graphql/fragment_cache/field_extension.rb:52:in `resolve'
rails_1 | /usr/local/bundle/gems/graphql-1.10.10/lib/graphql/schema/field.rb:757:in `run_extensions_before_resolve'
rails_1 | /usr/local/bundle/gems/graphql-1.10.10/lib/graphql/schema/field.rb:739:in `with_extensions'
rails_1 | /usr/local/bundle/gems/graphql-1.10.10/lib/graphql/schema/field.rb:561:in `resolve'
This line of code in this gem, is producing a deprecation warning with Rails 7.1
But only in the test
environment.
DEPRECATION WARNING: Support for `config.active_support.cache_format_version = 6.1` has been deprecated and will be removed in Rails 7.2
It doesn't matter if you set config.active_support.cache_format_version = 7.1
in the Rails environment or intializer, the deprecation warning will still happen.
This is because that line of code is executing before Rails gets a chance to boot and set the correct cache_format_version
.
If using RSpec, a possible workaround for now, is in rails_helper.rb
to set the cache format version prior to the gem being loaded. e.g.
require "spec_helper"
# NOTE: this is a fix for graphql-fragment_cache, which is initializing it's own cache in the test environment
require "active_support/cache"
ActiveSupport::Cache.format_version = 7.1
require File.expand_path("../config/environment", __dir__)
require "rspec/rails"
RSpec.configure do |config|
...
Hi there,
ENV:
We are currently using your gem on our Rails api which passes data through to an Apollo Angular app. We originally had a pure rails solution but got better performance results with your gem.
Issue:
The problem is that sometimes the cache returns null. This doesn't happen locally but happens when we use the cache on Redis for staging and production. The cached data is returned most of the time but sometimes returns null. We have investigated as much as we could: we first thought it might be the front end but we have narrowed it down to the cache returning null.
How to reproduce:
This only works some of the time
Question:
Do you have any ideas on what might be causing this or what we might be able to do? Thank you in advance.
class QueryType < GraphQL::Schema::Object
field :post, PostType, null: true do
argument :id, ID, required: true
end
def post(id:)
cache_fragment(context_dependent: true) { Post.find(id) }
end
end
Hi, I am trying to upgrade the gem to the latest version (1.8.0) and ran into some problems. We are using ddtracerb and it is expecting to receive a hash instead of an array to write_multi function:
This is the error rescued and then raised by your code:
GraphQL::FragmentCache::WriteMultiError:
undefined method 'keys' for ["graphql/ids/368d52c087dfcf3113a577315c45e3036b316410", {"data": "test"}]:Array
keys: hash.keys,
^^^^^
/home/circleci/.rubygems/gems/graphql-fragment_cache-1.18.0/lib/graphql/fragment_cache/cacher.rb:52:in `rescue in block in batched_persist'
And this is the original error:
--- Caused by: ---
NoMethodError:
undefined method `keys' for ["graphql/ids/368d52c087dfcf3113a577315c45e3036b316410", {"data":"test"}]:Array
keys: hash.keys,
^^^^^
/home/circleci/.rubygems/gems/ddtrace-1.8.0/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb:234:in `write_multi'
This is the code where it comes from: ddtrace code
Also the ruby version used is: 3.1.3
It seems to work fine when the resolver returns a collection, and when a resolver returns a single object that is not cached. But, when there's a cache-hit, I always get this error:
E GraphqlController -- Failed to implement Post.id, tried:
- `Types::Post#id`, which did not exist
- `PostDecorator#id`, which did not exist
- Looking up hash key `:id` or `"id"` on `#<GraphQL::Execution::Interpreter::RawValue:0x00000001105e7980>`, but it wasn't a Hash
To implement this field, define one of the methods above (and check for typos)
12:45:58 E GraphqlController -- /Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/schema/field.rb:848:in `block in public_send_field'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/schema/field.rb:911:in `with_extensions'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/schema/field.rb:803:in `public_send_field'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/schema/field.rb:717:in `block in resolve'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/schema.rb:118:in `after_lazy'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/schema/field.rb:715:in `resolve'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:511:in `block (4 levels) in evaluate_selection_with_args'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/tracing.rb:81:in `call_tracers'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/tracing.rb:83:in `block in call_tracers'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-fragment_cache-1.11.0/lib/graphql/fragment_cache/schema/tracer.rb:12:in `trace'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/tracing.rb:83:in `call_tracers'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/tracing.rb:67:in `trace'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:510:in `block (3 levels) in evaluate_selection_with_args'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/query.rb:366:in `block in with_error_handling'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/errors.rb:107:in `with_error_handling'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/query.rb:365:in `with_error_handling'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:509:in `block (2 levels) in evaluate_selection_with_args'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:812:in `call_method_on_directives'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:506:in `block in evaluate_selection_with_args'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:915:in `after_lazy'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:440:in `evaluate_selection_with_args'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:428:in `evaluate_selection'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:359:in `block (2 levels) in evaluate_selections'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/dataloader/null_dataloader.rb:17:in `append_job'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:358:in `block in evaluate_selections'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:357:in `each'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:357:in `evaluate_selections'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:739:in `block (3 levels) in continue_field'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:812:in `call_method_on_directives'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:738:in `block (2 levels) in continue_field'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:190:in `tap_or_each'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:729:in `block in continue_field'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:915:in `after_lazy'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:715:in `continue_field'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:520:in `block (3 levels) in evaluate_selection_with_args'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:915:in `after_lazy'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:517:in `block (2 levels) in evaluate_selection_with_args'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:812:in `call_method_on_directives'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:506:in `block in evaluate_selection_with_args'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:915:in `after_lazy'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:440:in `evaluate_selection_with_args'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:432:in `block in evaluate_selection'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/schema/member/has_arguments.rb:204:in `block (3 levels) in coerce_arguments'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/dataloader/null_dataloader.rb:17:in `append_job'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/schema/member/has_arguments.rb:185:in `block (2 levels) in coerce_arguments'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/schema/member/has_arguments.rb:184:in `each'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/schema/member/has_arguments.rb:184:in `block in coerce_arguments'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/schema/member/has_arguments.rb:213:in `coerce_arguments'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/arguments_cache.rb:52:in `dataload_for'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:431:in `evaluate_selection'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:359:in `block (2 levels) in evaluate_selections'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/dataloader/null_dataloader.rb:17:in `append_job'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:358:in `block in evaluate_selections'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:357:in `each'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:357:in `evaluate_selections'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:231:in `block (4 levels) in run_eager'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:812:in `call_method_on_directives'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:230:in `block (3 levels) in run_eager'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/dataloader/null_dataloader.rb:17:in `append_job'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:228:in `block (2 levels) in run_eager'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:190:in `tap_or_each'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:219:in `block in run_eager'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:812:in `call_method_on_directives'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter/runtime.rb:210:in `run_eager'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter.rb:73:in `block in evaluate'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/tracing.rb:81:in `call_tracers'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/tracing.rb:83:in `block in call_tracers'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-fragment_cache-1.11.0/lib/graphql/fragment_cache/schema/tracer.rb:12:in `trace'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/tracing.rb:83:in `call_tracers'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/tracing.rb:67:in `trace'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter.rb:72:in `evaluate'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/interpreter.rb:48:in `begin_query'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/multiplex.rb:85:in `begin_query'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/multiplex.rb:104:in `block (2 levels) in run_as_multiplex'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/dataloader/null_dataloader.rb:17:in `append_job'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/multiplex.rb:104:in `block in run_as_multiplex'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/multiplex.rb:103:in `each'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/multiplex.rb:103:in `each_with_index'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/multiplex.rb:103:in `run_as_multiplex'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/multiplex.rb:63:in `block (2 levels) in run_queries'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/multiplex.rb:211:in `block in instrument_and_analyze'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/instrumentation.rb:29:in `block (2 levels) in apply_instrumenters'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/instrumentation.rb:46:in `block (2 levels) in each_query_call_hooks'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/instrumentation.rb:46:in `block (2 levels) in each_query_call_hooks'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/instrumentation.rb:41:in `each_query_call_hooks'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/instrumentation.rb:45:in `block in each_query_call_hooks'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/instrumentation.rb:72:in `call_hooks'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/instrumentation.rb:44:in `each_query_call_hooks'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/instrumentation.rb:45:in `block in each_query_call_hooks'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/instrumentation.rb:72:in `call_hooks'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/instrumentation.rb:44:in `each_query_call_hooks'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/instrumentation.rb:27:in `block in apply_instrumenters'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/instrumentation.rb:72:in `call_hooks'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/instrumentation.rb:26:in `apply_instrumenters'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/multiplex.rb:190:in `instrument_and_analyze'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/multiplex.rb:62:in `block in run_queries'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/tracing.rb:81:in `call_tracers'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/tracing.rb:83:in `block in call_tracers'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-fragment_cache-1.11.0/lib/graphql/fragment_cache/schema/tracer.rb:12:in `trace'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/tracing.rb:83:in `call_tracers'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/tracing.rb:67:in `trace'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/multiplex.rb:60:in `run_queries'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/execution/multiplex.rb:50:in `run_all'
/Users/victor/.rvm/gems/ruby-2.7.4/gems/graphql-1.13.10/lib/graphql/schema.rb:1767:in `multiplex'
/Users/victor/Development/project/app/controllers/graphql_controller.rb:49:in `create'
I can call .resolve
on this and get a Hash, but then some custom relationships that access object.comments
would fail as it's now a Hash, which means I probably need to Post.build(cache_fragment { }.resolve)
or something, but from what I understand this should not be needed.
For what it's worth, I have a custom field class that looks like:
module Types::Base
class Field < GraphQL::Schema::Field
argument_class Types::Base::Argument
# Pass `field ..., unauthorized: true` to allow public requests
def initialize(*args, unauthorized: false, **kwargs, &block)
@unauthorized = unauthorized
super(*args, **kwargs, &block)
end
# Only allow logged in users unless authorized: true
def authorized?(obj, args, ctx)
return true if @unauthorized
return false unless ctx[:current_user].present?
true
end
end
end
I have included it in my schema like so:
class ProjectSchema < GraphQL::Schema
use GraphQL::FragmentCache
use GraphQL::Subscriptions::ActionCableSubscriptions, serializer: Subscriptions::Serialize
mutation(Types::MutationType)
query(Types::QueryType)
subscription(Types::SubscriptionType)
use GraphQL::Decorate
and applied it to my base resolver:
module Resolvers
class Base < GraphQL::Schema::Resolver
argument_class Types::Base::Argument
include GraphQL::FragmentCache::ObjectHelpers
...
and to my base object:
module Types::Base
class Object < GraphQL::Schema::Object
include GraphQL::FragmentCache::Object
include GraphQL::Decorate::ObjectIntegration
field_class(Types::Base::Field)
edge_type_class(Types::Base::Edge)
connection_type_class(Types::Base::Connection)
end
end
What am I doing wrong here?
What am I doing wrong here?
use GraphQL::FragmentCache, context_key: ->(context) { context[:current_user_id] }
use GraphQL::FragmentCache, context_key: : current_user_id
I am trying to use both fragment caching + action policy and due to lack of documentation I am unable to make it work if I have a authorized_scope: true
if my field
if I have a field like this:
field :collections, [CollectionType], null: false, authorized_scope: true, cache_fragment: { context_key: :current_user } do
I get an error:
Couldn't find policy class for.... "Couldn't find implicit authorization target for Types::QueryType. Please, provide policy class explicitly using `with` option or define the `implicit_authorization_target` method."] (Array)```
If I add a explicit policy:
field :collections, [CollectionType], null: false, authorized_scope: { with: CollectionTypePolicy }, cache_fragment: { context_key: :current_user } do
I get a different error:
Couldn't infer scope type for GraphQL::Execution::Interpreter::RawValue instance
It works flawlessly for fields without authorization scope, so not sure what I need to add/change on my end or what is missing
Forgive me if this is out of scope, or I am missing something here. The problem I am seeking to solve is let's say you have 50 people in a list, and they all have the same creator. The current Ruby GraphQL gem will call resolve and serialze the response 50 times. I've been playing around with this gem a bit and don't notice any difference at all in the performance of caching the result. But, I am also concerned because I don't really want to cache the result after the current request ends, because the data might change and I don't want to have to deal with cache invalidation. I was hoping this gem would allow me to resolve creator (and serialize it, which is where ruby_graphql seems to spend the most time) once.
people {
id
creator {
id
email
}
}
Hey there,
Love this gem. The examples show how to set cache keys for a single record. How do I expire cache keys for collections?
For example,
class Post < ApplicationRecord
has_many :comments
end
class Comment < ApplicationRecord
belongs_to :post
end
# somewhere in the GraphQL schema
field :posts, [PostType], null: false, cache_fragment: { context_key: [:current_user] }
I'm not sure how to expire the cached "posts" field.
I tried using "touch".
class Comment < ApplicationRecord
belongs_to :post, touch: true
end
But it's not expiring the posts field.
Hello,
Using GraphQL Ruby Multiplex with Apollo Batch Http Link, this user type works fine
def user(id:)
user = User.find(id)
cache_fragment([user, context[:current_user]]) do
user
end
end
but when I try to add GraphQL batch here
def user(id:)
Loaders::RecordLoader.for(User).load(id).then do |user|
cache_fragment([user, context[:current_user]]) do
user
end
end
end
I get this error:
undefined method `map' for nil:NilClass
/Users/jpalumickas/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/graphql-fragment_cache-1.4.0/lib/graphql/fragment_cache/cache_key_builder.rb:147:in `block in path_cache_key'
/Users/jpalumickas/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/graphql-fragment_cache-1.4.0/lib/graphql/fragment_cache/cache_key_builder.rb:144:in `fetch'
Also, this type with Batch works fine when using without Apollo Batch (calling single query)
I understand that you can setup namespace by either
GraphQL::FragmentCache.namespace = "my-prefix"
GraphQL::FragmentCache.configure { |config| config.namespace = "my-prefix" }
It isn't clear to me whether I can set namespace under config.default_options
, eg
GraphQL::FragmentCache.configure do |config|
config.default_options = {
namespace: "my-prefix"
}
end
However when I did the above, I got unexpected behaviour where the cache store tries to read the cache key without namespace but write with the namespace as part of the cache key.
Frankly I would expect namespace to be configured as part of the cache store options in which case each individual cache store would handle the namespace
Maybe it's just me, but I find the readme on this really confusing.
[README]
When using cache_fragment: option, it's only possible to use the resolved value as a cache key by setting:
field :post, PostType, null: true, cache_fragment: {cache_key: :object} do
argument :id, ID, required: true
end
# this is equal to
def post(id:)
cache_fragment(Post.find(id))
end
Also, you can pass :value to the cache_key: argument to use the returned value to build a key:
field :post, PostType, null: true, cache_fragment: {cache_key: :value} do
argument :id, ID, required: true
end
# this is equal to
def post(id:)
post = Post.find(id)
cache_fragment(post) { post }
end
[/README]
What is the difference between the "resolved value" being used vs. the "returned value"?
Also, it's not immediately clear how
def post(id:)
post = Post.find(id)
cache_fragment(post) { post }
end
AND
def post(id:)
cache_fragment(Post.find(id))
end
Are different.
Hi there,
We use https://github.com/Gusto/apollo-federation-ruby
When making federated queries that include fields that are cached with graphql-ruby-fragment_cache
, we get the error:
RuntimeError: Failed to look ahead the field: variations
Happy to look into this more, but not quite sure where to begin. Got any ideas?
Request body:
{
"query":"query($representations:[_Any!]!){_entities(representations:$representations){...on ProductCatalogProduct{name variations{id name texture{normalMapThumbnail{redirectUrl __typename}__typename}__typename}}}}",
"variables":{
"representations":[
{
"__typename":"ProductCatalogProduct",
"id":"0cb9b065-9153-40d0-873c-81da94e93d19"
}
]
}
}
Error stacktrace:
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/cache_key_builder.rb line 171 in block (2 levels) in path_cache_key
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/cache_key_builder.rb line 166 in map
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/cache_key_builder.rb line 166 in block in path_cache_key
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/cache_key_builder.rb line 163 in fetch
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/cache_key_builder.rb line 163 in path_cache_key
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/cache_key_builder.rb line 147 in block in query_cache_key
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/cache_key_builder.rb line 147 in fetch
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/cache_key_builder.rb line 147 in query_cache_key
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/cache_key_builder.rb line 129 in build
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/cache_key_builder.rb line 114 in call
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/fragment.rb line 28 in cache_key
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/fragment.rb line 50 in value_from_cache
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/fragment.rb line 24 in read
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/object_helpers.rb line 37 in cache_fragment
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/field_extension.rb line 52 in resolve
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/schema/field.rb line 780 in run_extensions_before_resolve
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/schema/field.rb line 756 in with_extensions
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/schema/field.rb line 696 in public_send_field
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/schema/field.rb line 609 in block in resolve
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/schema.rb line 115 in after_lazy
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/schema/field.rb line 607 in resolve
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 272 in block (4 levels) in evaluate_selection_with_args
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 81 in call_tracers
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 83 in block in call_tracers
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/schema/tracer.rb line 12 in trace
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 83 in call_tracers
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 83 in block in call_tracers
File /usr/local/bundle/gems/apollo-federation-1.1.5/lib/apollo-federation/tracing/tracer.rb line 114 in execute_field
File /usr/local/bundle/gems/apollo-federation-1.1.5/lib/apollo-federation/tracing/tracer.rb line 50 in trace
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 83 in call_tracers
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 67 in trace
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 271 in block (3 levels) in evaluate_selection_with_args
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/query.rb line 364 in block in with_error_handling
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/errors.rb line 45 in with_error_handling
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/query.rb line 363 in with_error_handling
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 270 in block (2 levels) in evaluate_selection_with_args
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 432 in resolve_with_directives
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 267 in block in evaluate_selection_with_args
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 516 in after_lazy
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 214 in evaluate_selection_with_args
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 202 in evaluate_selection
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 142 in block (2 levels) in evaluate_selections
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/dataloader/null_dataloader.rb line 16 in append_job
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 141 in block in evaluate_selections
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 140 in each
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 140 in evaluate_selections
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 384 in block in continue_field
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 516 in after_lazy
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 378 in continue_field
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 425 in continue_field
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 405 in block (2 levels) in continue_field
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 516 in after_lazy
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 402 in block in continue_field
File /usr/local/bundle/gems/activerecord-6.1.3.1/lib/active_record/relation/delegation.rb line 88 in each
File /usr/local/bundle/gems/activerecord-6.1.3.1/lib/active_record/relation/delegation.rb line 88 in each
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 395 in continue_field
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 425 in continue_field
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 284 in block (3 levels) in evaluate_selection_with_args
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 516 in after_lazy
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 278 in block (2 levels) in evaluate_selection_with_args
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 432 in resolve_with_directives
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 267 in block in evaluate_selection_with_args
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 516 in after_lazy
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 214 in evaluate_selection_with_args
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 206 in block in evaluate_selection
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/schema/member/has_arguments.rb line 132 in block (2 levels) in coerce_arguments
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/dataloader/null_dataloader.rb line 16 in append_job
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/schema/member/has_arguments.rb line 111 in block in coerce_arguments
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/schema/member/has_arguments.rb line 110 in each
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/schema/member/has_arguments.rb line 110 in coerce_arguments
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/arguments_cache.rb line 49 in dataload_for
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 205 in evaluate_selection
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 142 in block (2 levels) in evaluate_selections
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/dataloader/null_dataloader.rb line 16 in append_job
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 141 in block in evaluate_selections
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 140 in each
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 140 in evaluate_selections
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 384 in block in continue_field
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 516 in after_lazy
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 378 in continue_field
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 369 in block in continue_field
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 516 in after_lazy
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 358 in continue_field
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 405 in block (2 levels) in continue_field
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 516 in after_lazy
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 402 in block in continue_field
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 395 in each
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 395 in continue_field
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 425 in continue_field
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 284 in block (3 levels) in evaluate_selection_with_args
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 516 in after_lazy
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 278 in block (2 levels) in evaluate_selection_with_args
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 432 in resolve_with_directives
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 267 in block in evaluate_selection_with_args
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 516 in after_lazy
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 214 in evaluate_selection_with_args
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 206 in block in evaluate_selection
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/schema/member/has_arguments.rb line 132 in block (2 levels) in coerce_arguments
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/dataloader/null_dataloader.rb line 16 in append_job
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/schema/member/has_arguments.rb line 111 in block in coerce_arguments
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/schema/member/has_arguments.rb line 110 in each
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/schema/member/has_arguments.rb line 110 in coerce_arguments
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/arguments_cache.rb line 49 in dataload_for
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 205 in evaluate_selection
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 142 in block (2 levels) in evaluate_selections
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/dataloader/null_dataloader.rb line 16 in append_job
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 141 in block in evaluate_selections
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 140 in each
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 140 in evaluate_selections
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 62 in block in run_eager
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/dataloader/null_dataloader.rb line 16 in append_job
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter/runtime.rb line 61 in run_eager
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter.rb line 77 in block in evaluate
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 81 in call_tracers
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 83 in block in call_tracers
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/schema/tracer.rb line 12 in trace
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 83 in call_tracers
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 83 in block in call_tracers
File /usr/local/bundle/gems/apollo-federation-1.1.5/lib/apollo-federation/tracing/tracer.rb line 54 in trace
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 83 in call_tracers
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 67 in trace
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter.rb line 76 in evaluate
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/interpreter.rb line 49 in begin_query
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/multiplex.rb line 85 in begin_query
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/multiplex.rb line 104 in block (2 levels) in run_as_multiplex
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/dataloader/null_dataloader.rb line 16 in append_job
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/multiplex.rb line 104 in block in run_as_multiplex
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/multiplex.rb line 103 in each
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/multiplex.rb line 103 in each_with_index
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/multiplex.rb line 103 in run_as_multiplex
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/multiplex.rb line 63 in block (2 levels) in run_queries
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/multiplex.rb line 208 in block in instrument_and_analyze
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/instrumentation.rb line 29 in block (2 levels) in apply_instrumenters
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/instrumentation.rb line 46 in block (2 levels) in each_query_call_hooks
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/instrumentation.rb line 41 in each_query_call_hooks
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/instrumentation.rb line 45 in block in each_query_call_hooks
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/instrumentation.rb line 72 in call_hooks
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/instrumentation.rb line 44 in each_query_call_hooks
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/instrumentation.rb line 27 in block in apply_instrumenters
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/instrumentation.rb line 72 in call_hooks
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/instrumentation.rb line 26 in apply_instrumenters
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/multiplex.rb line 187 in instrument_and_analyze
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/multiplex.rb line 62 in block in run_queries
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 81 in call_tracers
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 83 in block in call_tracers
File /usr/local/bundle/gems/graphql-fragment_cache-1.6.0/lib/graphql/fragment_cache/schema/tracer.rb line 12 in trace
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 83 in call_tracers
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 83 in block in call_tracers
File /usr/local/bundle/gems/apollo-federation-1.1.5/lib/apollo-federation/tracing/tracer.rb line 63 in execute_multiplex
File /usr/local/bundle/gems/apollo-federation-1.1.5/lib/apollo-federation/tracing/tracer.rb line 46 in trace
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 83 in call_tracers
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/tracing.rb line 67 in trace
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/multiplex.rb line 60 in run_queries
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/execution/multiplex.rb line 50 in run_all
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/schema.rb line 1691 in multiplex
File /usr/local/bundle/gems/graphql-1.12.6/lib/graphql/schema.rb line 1662 in execute
File /usr/src/app/app/controllers/graphql_controller.rb line 6 in execute
I have a spec that unit tests a cached graphql field using a custom spec helper.
The class to test and the spec look something like this:
# app/graphql/types/objects/post_type.rb
module Types
module Objects
class PostType < Base
field :comments, Types::Objects::CommentType.connection_type, cache_fragment: true
def comments
# ...
end
end
end
end
# spec/graphql/types/objects/post_type_spec.rb
module Types
module Objects
describe PostType do
subject(:post) { create(:post) }
describe '#comments' do
before { create_list(:comment, 2, post: post) }
it { expect(resolve(post, :comments).count).to eq 2 }
end
end
end
end
And the file that provides the resolve
helper method looks a bit like this:
# spec/support/graphql/helpers.rb
module GraphQL
module Helpers
def resolve(object, field, args = {})
query = GraphQL::Query.new(MyAppSchema, context: context)
field = subject.fields[field.to_s.camelize(:lower)]
type_instance = described_class.authorized_new(object, query.context)
args.transform_keys! { |arg| arg.to_s.underscore.to_sym }
resolved = field.resolve(type_instance, args, query.context)
if resolved.is_a?(GraphQL::Pagination::Connection)
resolved.nodes
else
resolved
end
end
end
end
But when I run the spec I get the following error:
NoMethodError:
undefined method `count' for #<GraphQL::Execution::Lazy:0x00007f7e583a5010>
# ./spec/graphql/types/objects/post_type_spec.rb:1287:in `block (4 levels) in <module:Objects>'
The problem is that in my graphql helper, resolved
is a GraphQL::Execution::Lazy
object, and this object behaves differently than a more traditional GraphQL::Pagination::Connection
object.
I am not familiar with graphql-ruby
's internals. I tried resolved.value
but I get another error
NoMethodError: undefined method `operation_type' for nil:NilClass
from /Users/jerome/.asdf/installs/ruby/2.7.1/lib/ruby/gems/2.7.0/gems/graphql-1.12.6/lib/graphql/query.rb:167:in `lookahead'
Maybe I somehow need to provide operation_type
in my helper, although I don't know what value I could provide and where. Or maybe I am on the wrong path.
Any idea what I would need to fix this? Like how to get the nodes from a GraphQL::Execution::Lazy
?
In the meantime I have disabled caching for the test environment with the following monkey patch. If noone has any idea, maybe converting my monkey patch into a PR could be an acceptable workaround.
Hi, Amazing gem, really useful and I love the api :D
I'm working on an api that sometimes returns massive amounts of data up to 27mB and the cached responses are a bit slow.
I'm guessing this has to do with parsing the cached data text to a hash/json. Do you think it's possible to speed this up at all?
the response time seems linearly correlated with response size
Thanks for the help!
Schema.tracer(GraphQL::FragmentCache::Schema::Tracer)` is deprecated; use module-based `trace_with` instead. See: https://graphql-ruby.org/queries/tracing.html
/usr/local/bundle/gems/graphql-fragment_cache-1.20.0/lib/graphql/fragment_cache.rb:34:in `use'
graphql-ruby 2.3.0 has deprecated .tracer
method.
First of all, thank you for your great gem!
I am running into the following issue tho: I have all_pages field:
field :all_pages, PageType.connection_type, null: true
When I resolve and cache it using the gem all the pages get cached - which makes sense of course.
def all_pages
cache_fragment {
chain = Page
chain = scope_status(chain, context[:stage])
chain = lookahead_for_collection(chain, lookahead)
chain = search_records(chain, search)
chain = order_records(chain, order)
chain.all
}
end
I am using the api in a Gatsby website. So whenever there is an update in my rails app a webhook gets posted to Gatsby Cloud to rebuild the site. This rebuild will fetch all pages with all available fields which is very heavy. Also because they are a lot.
Is there an option to cache all pages but only invalidate a single one (similar to rails.cache.fetch_multi) so that all pages that did not change get fetched from the cache except the one that changed? This would speed up my app significantly.
Thank you! ๐
Hey --
Wondering if there is a way to for the entire cache to clear for all queries as opposed to by query by query.
Is there a way to clear the cache of all cached fragments? Such as Rails.cache.clear?
Basically topic, but would like a way to only go through the cache under certain conditions (couldn't tell from code or docs if already supported). For example, if a particular query will explode the cardinality but I want the base case to be cached. Contrived example:
field :search_movies, [MovieResultType], null: false do
argument :query, String, required: false
end
def search_movies(query: nil)
cache_fragment(disabled: !query.blank?) do
Movie.do_expensive_search(query) # and expensive resolving
end
end
Hi! ๐ Thanks for this great library, it's wonderful.
The docs state that the the Rails cache functions cache_key_with_version
and cache_key
will be called if it exists, but it doesn't actually call them in the Rails cache key builder:
and cache_key_with_version
doesn't actually show up anywhere in the code except the README.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.