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