stackshareio/graphql-cache

Caching resolvers?

phyllisstein opened this issue · 12 comments

👋 Hey there! I've been looking at implementing graphql-cache in my application, and I'm running into a little trouble. Fair warning that I'm not totally sure, especially after reading your tests, that I've set things up in an idiomatic and expected way, but I'm mostly using resolver classes to manage my queries:

class Query < ApplicationObject
    field :author, resolver: Resolvers::Author
    # ...etc.
end
class ApplicationObject < GraphQL::Schema::Object
    field_class GraphQL::Cache::Field
end
module Resolvers
    class Author < GraphQL::Schema::Resolver
        description 'A single Author by slug or UUID.'

        type Types::Author, null: true

        argument :id, ID, required: true

        def resolve(id:)
            Users::Author.find_by(slug: id) || Users::Author.find(id)
        end
    end
end
class Schema < GraphQL::Schema
    query ::Query

    middleware GraphQL::Cache::Middleware
end

What I'm finding, though, is that if I try to tack cache: true onto one of the resolvers' fields, I get a nastygram and a 500 from Rails:

no _dump_data is defined for class Proc
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:807:in `dump'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:807:in `marshaled_value'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:787:in `should_compress?'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:718:in `initialize'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:445:in `new'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:445:in `block in write'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:663:in `block in instrument'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/notifications.rb:170:in `instrument'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:663:in `instrument'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:444:in `write'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-cache-0.2.5/lib/graphql/cache/marshal.rb:52:in `write'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-cache-0.2.5/lib/graphql/cache/marshal.rb:37:in `read'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-cache-0.2.5/lib/graphql/cache.rb:59:in `fetch'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-cache-0.2.5/lib/graphql/cache/middleware.rb:58:in `call'

I was hoping you might have some insight into how I could get these fields to be cacheable---unless this is just a totally backasswards way to build a schema, in which case I can reconsider my end of things. Thanks in advance for any thoughts you have!

Hi @phyllisstein thanks for checking the gem out. To be honest, I haven't tested the gem against resolver classes as of yet. What I'd recommend for the moment is to use master in your Gemfile:

gem 'graphql-cache', git: 'https://github.com/stackshareio/graphql-cache.git', sha: '5bf0fc9'

This will require making some small changes to the way you're setup. On master, in your schema file, use this syntax:

use GraphQL::Cache

(We refactored away from a middleware implementation to one that is similar to graphql-batch)

I'm not certain that this will resolve your problem, but will get us working against the newest copy so that we can figure out why resolver classes aren't working. In the meantime, I'll work on implementing some specs covering resolver classes to see if I can suss out what's wrong. Let me know what happens after you update.

Thanks for the suggestion! I've dropped in the master version of the gem and updated my setup as described, but unfortunately I'm still seeing the same error. The complete stack trace, which is a little verbose, is below; let me know if I can provide any additional color!

no _dump_data is defined for class Proc
no _dump_data is defined for class Proc
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:807:in `dump'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:807:in `marshaled_value'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:787:in `should_compress?'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:718:in `initialize'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:445:in `new'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:445:in `block in write'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:663:in `block in instrument'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/notifications.rb:170:in `instrument'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:663:in `instrument'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache.rb:444:in `write'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/bundler/gems/graphql-cache-5bf0fc9ec773/lib/graphql/cache/marshal.rb:52:in `write'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/bundler/gems/graphql-cache-5bf0fc9ec773/lib/graphql/cache/marshal.rb:37:in `read'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/bundler/gems/graphql-cache-5bf0fc9ec773/lib/graphql/cache/fetcher.rb:14:in `block in instrument'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/schema/member/instrumentation.rb:74:in `call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/field.rb:248:in `resolve'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/execute.rb:295:in `call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/schema/middleware_chain.rb:49:in `invoke_core'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/schema/middleware_chain.rb:38:in `invoke'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/execute.rb:108:in `block in resolve_field'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/tracing.rb:57:in `block in trace'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/tracing.rb:71:in `call_tracers'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/tracing.rb:57:in `trace'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/execute.rb:107:in `resolve_field'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/execute.rb:71:in `block in resolve_selection'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/execute.rb:64:in `each'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/execute.rb:64:in `resolve_selection'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/execute.rb:36:in `block in resolve_root_selection'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/tracing.rb:57:in `block in trace'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/tracing.rb:71:in `call_tracers'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/tracing.rb:57:in `trace'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/execute.rb:32:in `resolve_root_selection'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/multiplex.rb:108:in `begin_query'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/multiplex.rb:81:in `block in run_as_multiplex'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/multiplex.rb:80:in `map'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/multiplex.rb:80:in `run_as_multiplex'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/multiplex.rb:69:in `block (2 levels) in run_queries'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/multiplex.rb:174:in `block in instrument_and_analyze'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/instrumentation.rb:29:in `block (2 levels) in apply_instrumenters'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/instrumentation.rb:46:in `block (2 levels) in each_query_call_hooks'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/instrumentation.rb:41:in `each_query_call_hooks'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/instrumentation.rb:45:in `block in each_query_call_hooks'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/instrumentation.rb:70:in `block in call_hooks'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/instrumentation.rb:58:in `call_hooks'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/instrumentation.rb:69:in `call_hooks'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/instrumentation.rb:44:in `each_query_call_hooks'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/instrumentation.rb:27:in `block in apply_instrumenters'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/instrumentation.rb:58:in `call_hooks'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/instrumentation.rb:26:in `apply_instrumenters'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/multiplex.rb:166:in `instrument_and_analyze'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/multiplex.rb:68:in `block in run_queries'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/tracing.rb:57:in `block in trace'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/tracing.rb:71:in `call_tracers'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/tracing.rb:57:in `trace'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/multiplex.rb:58:in `run_queries'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/execution/multiplex.rb:48:in `run_all'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/schema.rb:341:in `block in multiplex'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/schema.rb:1056:in `with_definition_error_check'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/schema.rb:340:in `multiplex'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/graphql-1.8.5/lib/graphql/schema.rb:317:in `execute'
/Users/daniel/Repos/Ignota/structur-api/app/controllers/graphql_controller.rb:11:in `execute'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/abstract_controller/base.rb:194:in `process_action'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_controller/metal/rendering.rb:30:in `process_action'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/abstract_controller/callbacks.rb:42:in `block in process_action'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/callbacks.rb:98:in `run_callbacks'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/abstract_controller/callbacks.rb:41:in `process_action'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_controller/metal/rescue.rb:22:in `process_action'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_controller/metal/instrumentation.rb:34:in `block in process_action'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/notifications.rb:168:in `block in instrument'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/notifications/instrumenter.rb:23:in `instrument'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/notifications.rb:168:in `instrument'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_controller/metal/instrumentation.rb:32:in `process_action'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_controller/metal/params_wrapper.rb:256:in `process_action'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/abstract_controller/base.rb:134:in `process'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_controller/metal.rb:191:in `dispatch'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_controller/metal.rb:252:in `dispatch'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_dispatch/routing/route_set.rb:52:in `dispatch'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_dispatch/routing/route_set.rb:34:in `serve'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_dispatch/journey/router.rb:52:in `block in serve'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_dispatch/journey/router.rb:35:in `each'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_dispatch/journey/router.rb:35:in `serve'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_dispatch/routing/route_set.rb:840:in `call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/apollo_upload_server-2.0.0.beta.1/lib/apollo_upload_server/middleware.rb:20:in `call'
/usr/local/rvm/rubies/ruby-2.6.0-preview2/lib/ruby/gems/2.6.0/gems/rack-2.0.5/lib/rack/etag.rb:25:in `call'
/usr/local/rvm/rubies/ruby-2.6.0-preview2/lib/ruby/gems/2.6.0/gems/rack-2.0.5/lib/rack/conditional_get.rb:38:in `call'
/usr/local/rvm/rubies/ruby-2.6.0-preview2/lib/ruby/gems/2.6.0/gems/rack-2.0.5/lib/rack/head.rb:12:in `call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/neo4j-9.3.0/lib/neo4j/migrations/check_pending.rb:16:in `call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/callbacks.rb:98:in `run_callbacks'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_dispatch/middleware/callbacks.rb:26:in `call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_dispatch/middleware/executor.rb:14:in `call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_dispatch/middleware/debug_exceptions.rb:61:in `call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/railties-5.2.0/lib/rails/rack/logger.rb:38:in `call_app'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/railties-5.2.0/lib/rails/rack/logger.rb:26:in `block in call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/tagged_logging.rb:71:in `block in tagged'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/tagged_logging.rb:28:in `tagged'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/tagged_logging.rb:71:in `tagged'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/railties-5.2.0/lib/rails/rack/logger.rb:26:in `call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_dispatch/middleware/request_id.rb:27:in `call'
/usr/local/rvm/rubies/ruby-2.6.0-preview2/lib/ruby/gems/2.6.0/gems/rack-2.0.5/lib/rack/runtime.rb:22:in `call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/activesupport-5.2.0/lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_dispatch/middleware/executor.rb:14:in `call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/actionpack-5.2.0/lib/action_dispatch/middleware/static.rb:127:in `call'
/usr/local/rvm/rubies/ruby-2.6.0-preview2/lib/ruby/gems/2.6.0/gems/rack-2.0.5/lib/rack/sendfile.rb:111:in `call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/rack-cors-1.0.2/lib/rack/cors.rb:97:in `call'
/usr/local/rvm/gems/ruby-2.6.0-preview2@structur/gems/railties-5.2.0/lib/rails/engine.rb:524:in `call'
/usr/local/rvm/rubies/ruby-2.6.0-preview2/lib/ruby/gems/2.6.0/gems/passenger-5.3.3/src/ruby_supportlib/phusion_passenger/rack/thread_handler_extension.rb:97:in `process_request'
/usr/local/rvm/rubies/ruby-2.6.0-preview2/lib/ruby/gems/2.6.0/gems/passenger-5.3.3/src/ruby_supportlib/phusion_passenger/request_handler/thread_handler.rb:157:in `accept_and_process_next_request'
/usr/local/rvm/rubies/ruby-2.6.0-preview2/lib/ruby/gems/2.6.0/gems/passenger-5.3.3/src/ruby_supportlib/phusion_passenger/request_handler/thread_handler.rb:110:in `main_loop'
/usr/local/rvm/rubies/ruby-2.6.0-preview2/lib/ruby/gems/2.6.0/gems/passenger-5.3.3/src/ruby_supportlib/phusion_passenger/request_handler.rb:415:in `block (3 levels) in start_threads'
/usr/local/rvm/rubies/ruby-2.6.0-preview2/lib/ruby/gems/2.6.0/gems/passenger-5.3.3/src/ruby_supportlib/phusion_passenger/utils.rb:113:in `block in create_thread_and_abort_on_exception'

I'm having trouble reproducing this error. Can you provide the field/resolver definitions with the cache: true so I can verify that's in the right place? Also, what version of ruby and graphql-ruby are you using?

Aha, after a little experimentation, it turns out the issue was that the resolve method was returning a Hash:

module Resolvers
    class PostsByPage < ApplicationResolver
        description 'Fetches a paginated list of posts.'

        type Types::PostsByPage, null: false

        argument :cursor, ID, required: false

        def resolve(cursor:)
            posts = if cursor.blank?
                        Content::Post.first_page
                    else
                        Content::Post.next_page_from cursor: cursor
                    end

            return if posts.count.zero?

            last_cursor = Base64.encode64(posts.last.published_at.to_formatted_s(:iso8601))
            metadata = PaginationMetadata.new count: Content::Post::PAGE_COUNT,
                                              cursor: last_cursor,
                                              total: Content::Post.count

            { pagination: metadata, posts: posts }
        end
    end
end
module Types
    class PostsByPage < ApplicationObject
        description 'A list of Posts with pagination metadata.'

        field :pagination, Types::PaginationMetadata, null: false
        field :posts, [Types::Post, null: true], null: false
    end
end

Resolvers that return model objects directly work beautifully---which is exciting!---it's just the hash that's causing the issue.

Thanks for the update! I'm not able to reproduce in the test schema even when returning a hash. The test schema uses mini_cache which may cover over an issue with serializing hashes to cache. I'm going to spin up an example Rails app to try and reproduce with Rails.cache later today. I might have to serialize hashes in and out of JSON explicitly. I'll reply here when I know more.

Also, just so there are no surprises, are you using the default Rails cache store, or something like Redis or Memcached?

This is a facepalm on my end, I'm afraid: the posts object in that hash was a Neo4j QueryProxy object, which was causing the cache to choke. Single objects worked fine because they're based on ActiveModel, but query proxies with multiple results aren't something Rails has any idea how to deal with. Turned out to be as simple as:

diff --git a/app/graphql/resolvers/posts_by_page.rb b/app/graphql/resolvers/posts_by_page.rb
index 5273c8a..f3a9c6f 100644
--- a/app/graphql/resolvers/posts_by_page.rb
+++ b/app/graphql/resolvers/posts_by_page.rb
@@ -22,7 +22,7 @@ module Resolvers
                                               cursor: last_cursor,
                                               total: Content::Post.count
 
-            { pagination: metadata, posts: posts }
+            { pagination: metadata, posts: posts.to_a }
         end
     end
 end

Apologies for the wild goose chase. I think this can safely be closed.

The reason behind:

no _dump_data is defined for class Proc

is that somewhere in your application you are trying to cache a Proc or block object, and since these objects are not-cacheable you are ending up with this issue. This is totally unrelated to this gem.

On the tangent, I want to use caching with resolver classes too, I've tried to plug in cache: true at multiple spots and it doesn't work anywhere. :/

@jasdeepsingh cache: true should be added to the field definition, regardless of how the field is resolved. What is the log output when you run a query that selects the cached field? Also, do you have caching enabled in development?

@thebadmonkeydev: yes, I’ve tried to added it to the field definition and caching in development is enabled as well. Yet, still doesn’t work. I’ll try one more time again today.

What is the output of your rails s log during query execution? You should see some output from the gem in development.

(Reopening so I can track this conversation better)

Closing this since it is stale.