Skip to content

SchemaClassScanner doesn't scan directive arguments #664

Closed

Description

@oryan-block

Description

Custom scalars and input objects used in directives are not scanned, and subsequently their type cannot be determined when building directives in SchemaParser

Expected behavior

scalar CustomScalar
directive @something(arg: CustomScalar) on FIELD_DEFINITION

type Query {
    allProducts: [Product]
}

type Product {
    name: String @something(arg: "1")
}

Should parse successfully

Actual behavior

graphql.kickstart.tools.SchemaError: Expected type 'CustomScalar' to be a GraphQLInputType, but it wasn't! Was a type only permitted for object types incorrectly used as an input type, or vice-versa?

Activity

  1. enriquedacostacambio commented on Aug 25, 2022

    @enriquedacostacambio

    This causes apollo-federated schemas to fail because _FieldSet is only used in directives.

    Caused by: graphql.kickstart.tools.SchemaError: Expected type '_FieldSet' to be a GraphQLInputType, but it wasn't!  Was a type only permitted for object types incorrectly used as an input type, or vice-versa?
    	at graphql.kickstart.tools.SchemaParser.determineType(SchemaParser.kt:355) ~[graphql-java-tools-13.0.0.jar:na]
    	at graphql.kickstart.tools.SchemaParser.determineInputType(SchemaParser.kt:373) ~[graphql-java-tools-13.0.0.jar:na]
    	at graphql.kickstart.tools.SchemaParser.determineInputType(SchemaParser.kt:365) ~[graphql-java-tools-13.0.0.jar:na]
    	at graphql.kickstart.tools.SchemaParser.createDirective(SchemaParser.kt:307) ~[graphql-java-tools-13.0.0.jar:na]
    	at graphql.kickstart.tools.SchemaParser.parseSchemaObjects(SchemaParser.kt:83) ~[graphql-java-tools-13.0.0.jar:na]
    	at graphql.kickstart.tools.SchemaParser.makeExecutableSchema(SchemaParser.kt:110) ~[graphql-java-tools-13.0.0.jar:na]
    
  2. enriquedacostacambio commented on Sep 7, 2022

    @enriquedacostacambio

    this can be reproduced with:

    package test;
    
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    import org.junit.Test;
    
    import graphql.GraphQL;
    import graphql.kickstart.tools.GraphQLQueryResolver;
    import graphql.kickstart.tools.SchemaParser;
    import graphql.kickstart.tools.SchemaParserBuilder;
    import graphql.scalar.GraphqlStringCoercing;
    import graphql.schema.DataFetchingEnvironment;
    import graphql.schema.GraphQLScalarType;
    import graphql.schema.GraphQLSchema;
    
    public class IssueTest {
        static class MockQueryResolver implements GraphQLQueryResolver {
            public String mockField(String input, DataFetchingEnvironment environment) {
                return null;
            }
        };
        
        @Test
        public void testUsedInField() {
            // this passes
            graphQl(
                "scalar MockScalar",
                "directive @mockDirective(arg: MockScalar) on FIELD_DEFINITION",
                "type Query {",
                "    mockField(input: MockScalar): String @mockDirective(arg: \"mock-value\")",
                "}"
            );
        }
        
        @Test
        public void testUsedOnlyInDirectives() {
            // this fails with:
            // graphql.kickstart.tools.SchemaError: Expected type 'MockScalar' to be
            // a GraphQLInputType, but it wasn't!  Was a type only permitted for
            // object types incorrectly used as an input type, or vice-versa?
            graphQl(
                "scalar MockScalar",
                "directive @mockDirective(arg: MockScalar) on FIELD_DEFINITION",
                "type Query {",
                "    mockField(input: String) : String @mockDirective(arg: \"mock-value\")",
                "}"
            );
        }
        
        private GraphQL graphQl(String... sdl) {
            SchemaParserBuilder builder = new SchemaParserBuilder();
            builder.schemaString(Stream.of(sdl).collect(Collectors.joining("\n")));
            SchemaParser schemaParser = builder
                .resolvers(new MockQueryResolver())
                .scalars(GraphQLScalarType.newScalar()
                    .name("MockScalar")
                    .coercing(new GraphqlStringCoercing())
                    .build()
                )
                .build();
            GraphQLSchema schema = schemaParser.makeExecutableSchema();
            return GraphQL.newGraphQL(schema).build();
        }
    }
  3. enriquedacostacambio commented on Sep 30, 2022

    @enriquedacostacambio

    @oryan-block is this easy to fix? i never coded in kotlin but if you give me a few pointers I can give it a shot.

  4. oryan-block commented on Oct 3, 2022

    @oryan-block
    CollaboratorAuthor

    Unfortunately because of the way the scanner works and how different directives are from everything else, this is not a trivial fix.

  5. anbusampath commented on Dec 6, 2022

    @anbusampath
  6. oryan-block commented on Sep 18, 2023

    @oryan-block
    CollaboratorAuthor

    This should be partially resolved by #763 for scalars.
    However, directives with input object arguments/parameters are still not supported (this was the case even before the applied directives change)

  7. airvine-r7 commented on Sep 20, 2023

    @airvine-r7

    @oryan-block Any updates on this or work arounds?

    This should be partially resolved by #763 for scalars. However, directives with input object arguments/parameters are still not supported (this was the case even before the applied directives change)

  8. oryan-block commented on Sep 20, 2023

    @oryan-block
    CollaboratorAuthor

    @airvine-r7 that fix is merged. You can test it now.
    #764 is a more complete solution I think should make directives fully supported.

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