Skip to content

graphql.AssertException when using graphql-java-tools (5.6.1) with apollo federation-jvm #300

Closed
@marmys

Description

@marmys

Hi

I'm trying to use apollo federation-jvm together with graphql-java-tools (5.6.1)
https://github.com/apollographql/federation-jvm
This is a library that "federate" graphql-java schema so that this schema can be used later by apollo federation gateway.
https://www.apollographql.com/docs/apollo-server/federation/introduction/

federation-jvm works with graphql-java but does not work with graphql-java-tools.
When I try to run it with graphql-java-tools i got an error:

Caused by: graphql.AssertException: All types within a GraphQL schema must have unique names. No two provided types may have the same name.
No provided type may have a name which conflicts with any built in types (including Scalar and Introspection types).
You have redefined the type 'Query' from being a 'GraphQLObjectType' to a 'GraphQLObjectType'
	at graphql.schema.GraphQLTypeCollectingVisitor.assertTypeUniqueness(GraphQLTypeCollectingVisitor.java:105) ~[graphql-java-13.0.jar:na]
    at graphql.schema.GraphQLTypeCollectingVisitor.visitGraphQLObjectType(GraphQLTypeCollectingVisitor.java:38) ~[graphql-java-13.0.jar:na]
	at graphql.schema.GraphQLObjectType.accept(GraphQLObjectType.java:174) ~[graphql-java-13.0.jar:na]
	at graphql.schema.TypeTraverser$TraverserDelegateVisitor.enter(TypeTraverser.java:71) ~[graphql-java-13.0.jar:na]
	at graphql.util.Traverser.traverse(Traverser.java:147) ~[graphql-java-13.0.jar:na]
	at graphql.schema.TypeTraverser.doTraverse(TypeTraverser.java:58) ~[graphql-java-13.0.jar:na]
	at graphql.schema.TypeTraverser.depthFirst(TypeTraverser.java:50) ~[graphql-java-13.0.jar:na]
	at graphql.schema.TypeTraverser.depthFirst(TypeTraverser.java:38) ~[graphql-java-13.0.jar:na]
	at graphql.schema.SchemaUtil.allTypes(SchemaUtil.java:42) ~[graphql-java-13.0.jar:na]
	at graphql.schema.GraphQLSchema.<init>(GraphQLSchema.java:102) ~[graphql-java-13.0.jar:na]
	at graphql.schema.GraphQLSchema.<init>(GraphQLSchema.java:37) ~[graphql-java-13.0.jar:na]
	at graphql.schema.GraphQLSchema$Builder.build(GraphQLSchema.java:411) ~[graphql-java-13.0.jar:na]
	at com.apollographql.federation.graphqljava.SchemaTransformer.build(SchemaTransformer.java:134) ~[classes/:na]

As I investigated this is because when graphql-java-tools creates schema it passes every type as additionalTypes.
See SchemaParser.kt line 129

return SchemaObjects(query, mutation, subscription, (objects + inputObjects + enums + interfaces + unions).toSet(), codeRegistryBuilder)

4th argument is used as additionalTypes and graphql-java-tools puts every type in it including "Query" type.

In graphql-java additionalTypes are only types that are not referenced from the top level operations.

See SchemaGenerator.java (graphq-java 13.0) line 362

/**
 * We build the query / mutation / subscription path as a tree of referenced types
 * but then we build the rest of the types specified and put them in as additional types
 *
 * @param buildCtx the context we need to work out what we are doing
 *
 * @return the additional types not referenced from the top level operations
 */
private Set<GraphQLType> buildAdditionalTypes(BuildContext buildCtx) {

To get example that does not work:
use federation-jvm example
https://github.com/apollographql/federation-jvm/tree/master/spring-example/src/main/java/com/apollographql/federation/springexample

with modifications:

  • add graphql-java-tools 5.6.1 to pom.xml
  • simplify graphql schema in inventory.graphql to
    type Query {
      aQuery: String!
    }
  • add simple resolver for this query
    package com.apollographql.federation.springexample;
    import com.coxautodev.graphql.tools.GraphQLQueryResolver;
    public class QueryResolver implements GraphQLQueryResolver {
        public String aQuery() {
            return "aValue";
        }
    }
  • modify InventorySchemaProvider class:
    @Component
    public class InventorySchemaProvider extends DefaultGraphQLSchemaProvider implements 
    GraphQLSchemaProvider {
        public InventorySchemaProvider(@Value("classpath:schemas/inventory.graphql") Resource sdl) throws Exception {
            super(Federation.transform(buildSchema(sdl)).build());
        }

        private static GraphQLSchema buildSchema(Resource sdl) throws Exception {
            SchemaParserBuilder parserBuilder = com.coxautodev.graphql.tools.SchemaParser.newParser();
            parserBuilder.schemaString(CharStreams.toString(new InputStreamReader(sdl.getInputStream(), UTF_8)));
            parserBuilder.resolvers(new QueryResolver());
            return parserBuilder.build().makeExecutableSchema();
        }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions