graphql-ruby icon indicating copy to clipboard operation
graphql-ruby copied to clipboard

Schema.types doesn't contain orphan types

Open fameoflight opened this issue 2 years ago • 2 comments

Describe the bug

when querying all the types in Schema.types it doesn't contain orphan types.

It does contain orphan types when I run this in Rails Console. So I am assuming this builds up the cache over time. How do I force Schema to build this cache ASAP. I am using these typenames as enum value in one of my query.

fameoflight avatar Jun 27 '22 15:06 fameoflight

Hey, could you share an example of this?

Types that aren't connected to the schema an input type or return type are excluded from the schema, even if they're given to orphan_types. (This is how GraphQL-Ruby implements "visibility", where some types and fields can be hidden.) Is the orphan type you're looking for connected to the schema as an input type or return type?

rmosolgo avatar Jun 29 '22 14:06 rmosolgo

I am using them in customNode query wherein I pass id and graphql name. As an example let's say I have two different graphql schema types UserType and MiniUserType now, UserType is not all connected anywhere in schema, and only way to query is using customNode query

I wanted to make these name parameter enum (rather than String) to have typesafety on frontend.

fameoflight avatar Jul 01 '22 23:07 fameoflight

Sorry I haven't been back to this for a while!

I implemented a little script based on your description:

require "bundler/inline"

gemfile do
  gem "graphql", "2.0.15"
end

class Schema < GraphQL::Schema

  module CustomNode
    include GraphQL::Schema::Interface

    field :id, ID
  end

  class CustomNodeName < GraphQL::Schema::Enum
    value "Thing"
    value "MiniThing"
  end

  class Thing < GraphQL::Schema::Object
    implements CustomNode
  end

  class MiniThing < GraphQL::Schema::Object
    implements CustomNode
  end

  class Query < GraphQL::Schema::Object
    field :custom_node, CustomNode do
      argument :id, ID
      argument :type_name, CustomNodeName
    end

    def custom_node(id:, type_name:)
      { id: id, type_name: type_name } # pretend this is the fetched object
    end
  end

  query(Query)

  orphan_types(Thing, MiniThing)

  def self.resolve_type(_type, obj, ctx)
    Schema.const_get(obj[:type_name])
  end
end

query_str = <<-GRAPHQL
{
  customNode(id: \"1\", typeName: MiniThing) {
    id
    __typename
  }
}
GRAPHQL

pp Schema.execute(query_str).to_h
puts "---------"
puts Schema.to_definition

And to my eyes, it works as expected:

{"data"=>{"customNode"=>{"id"=>"1", "__typename"=>"MiniThing"}}}
---------
interface CustomNode {
  id: ID
}

enum CustomNodeName {
  MiniThing
  Thing
}

type MiniThing implements CustomNode {
  id: ID
}

What's key is:

  • MiniThing must have implements CustomNode;
  • And, MiniThing must be in orphan_types ... (because it's not otherwise the return type of a field)

How does that script compare to your situation? Could you share the source of your Custom Node type and one of the orphan types that isn't appearing?

rmosolgo avatar Nov 22 '22 14:11 rmosolgo

I hope you found something that works for you! Please open a new issue if you run into more trouble on this.

rmosolgo avatar Oct 17 '23 19:10 rmosolgo