Skip to content

Directive wirings see a type reference on recursive input fields #875

Open

Description

@oryan-block

A SchemaDirectiveWiring that looks at the type of a recursive input field gets a GraphQLTypeReference instead of the input object:

directive @check on INPUT_FIELD_DEFINITION

type Query {
    trees(filter: Tree): Int
}

input Tree {
    and: [Tree!] @check
    name: String @check
}

In onInputObjectField, GraphQLTypeUtil.unwrapAll(element.type) is a GraphQLTypeReference for and (name is a GraphQLScalarType as expected). The same schema and wiring through plain graphql-java's SchemaGenerator gives a GraphQLInputObjectType for and.

So any wiring that walks input types and calls unwrapAll fails with ClassCastException: GraphQLTypeReference cannot be cast to GraphQLUnmodifiedType. I believe that includes graphql-java-extended-validation's DirectivesAndTypeWalker, but I haven't run it against this schema.

#843 fixed the non-recursive case (input objects behind a list or non-null wrapper) and left cycles out. Types are immutable, so one field of a cycle has to stay a reference while the type is being built. graphql-java only runs directive wirings once the whole schema is assembled, so its wirings never see that reference. Ours run while types are being built, so they do.

The fix is probably to hold off all directive wiring until the schema is assembled. That touches objects, interfaces, unions and enums too, not just input objects. I haven't prototyped it.

Not the same as #36 or #450. Those were about recursive inputs not building at all, and that's fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions