0

Usually, in GraphQL/Rails you have a query_type.rb file that would look something like this:

module Types
  class QueryType < Types::BaseObject
    # Add root-level fields here.
    # They will be entry points for queries on your schema.

    field :test_field, String, null: false do
      description 'Test field'
    end
    def test_field
      'My test field!'
    end
  end
end

All of my queries are in this file full implemented. Is there a way to do something like mutation_type.rb does and scope the query implementations out into other files? Maybe something like this?:

query_type.rb:

module Types
  class QueryType < Types::BaseObject
    # Add root-level fields here.
    # They will be entry points for queries on your schema.
    field :test_field, String, null: false, query: Types::TestFieldType
  end
end

test_field_type.rb:

module Types
  class TestFieldType < Types::BaseObject
    description 'Test Field'

    def test_field
      'My Test field!'
    end
  end
end
aarona
  • 35,986
  • 41
  • 138
  • 186
  • Do you mean like `field :test_field, Types::TestFieldType, null: false`? – 3limin4t0r Oct 06 '20 at 17:06
  • I'm looking for a way to pull my queries out of `query_type.rb` into their own files like you do with mutations. It makes reading code more manageable in my opinion. – aarona Oct 06 '20 at 17:08

2 Answers2

1

You can create your own custom field class that accepts arbitrary keyword parameters such as query as in your example above.

You could create:

class MyField
  def self.call
    # implement
  end
end

class Types::ClassBasedField < GraphQL::Schema::Field
  def initialize(*args, query: nil, **kwargs, &block)
    super(*args, **kwargs, &block)

    return unless query

    # some metaprogramming here to define a method that invokes
    # your own query class implementation if provided
    #
    # Maybe something like this (untested)
    define_method(args[0], &query.method(:call))
  end
end

# within BaseObject
field_class Types::ClassBasedField

More on how to use custom field classes: https://graphql-ruby.org/type_definitions/extensions.html

Stephen Crosby
  • 1,157
  • 7
  • 19
1

GraphQL Ruby supports resolvers which can be used to contain resolution logic. I've never had to use this myself and currently don't have the environment set-up to test this, but it might point you in the right direction.

Check out the resolver documentation linked above for more info.

# app/graphql/resolvers/base.rb
module Resolvers
  class Base < GraphQL::Schema::Resolver; end
end
# app/graphql/resolvers/test_field.rb
module Resolvers
  class TestField < Resolvers::Base
    type String, null: false
    description 'Test Field'

    def resolve
      'My test field!'
    end
  end
end
# app/graphql/types/query_type.rb
module Types
  class QueryType < Types::BaseObject
    # Add root-level fields here.
    # They will be entry points for queries on your schema.
    field :test_field, resolver: Resolvers::TestField
  end
end
3limin4t0r
  • 19,353
  • 2
  • 31
  • 52