Skip to content

SchemaClassScanner doesn't scan directive arguments #664

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
oryan-block opened this issue May 19, 2022 · 8 comments · Fixed by #763 or #764
Closed

SchemaClassScanner doesn't scan directive arguments #664

oryan-block opened this issue May 19, 2022 · 8 comments · Fixed by #763 or #764
Labels

Comments

@oryan-block
Copy link
Collaborator

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?

@enriquedacostacambio
Copy link

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]

@enriquedacostacambio
Copy link

enriquedacostacambio commented Sep 7, 2022

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();
    }
}

@enriquedacostacambio
Copy link

@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.

@oryan-block
Copy link
Collaborator Author

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

@anbusampath
Copy link

#725

@oryan-block
Copy link
Collaborator Author

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)

@airvine-r7
Copy link

@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)

@oryan-block
Copy link
Collaborator Author

@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
Labels
Projects
None yet
4 participants