Open
Description
Overview: I am encountering an incompatibility issue between graphql-spqr and com.apollographql.federation when using entity interfaces, as outlined in the Apollo Federation documentation.
Details: The GraphQLSchema generated by graphql-spqr cannot be processed by Apollo's Federation.transform()
method. This results in a ClassCastException
, specifically:
Caused by: java.lang.ClassCastException: class java.lang.String cannot be cast to class graphql.language.StringValue
That ClassCastException
occurs on this line of the Apollo code.
Context: This exception arises when a GraphQL Interface is included in the _entity federated types. Below is a snippet of the relevant code:
@GraphQLDirective(name = "key")
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface KeyDirective {
String fields();
}
@KeyDirective(fields = "foo")
@GraphQLInterface(name = "MyInterface")
public interface MyInterface {
@GraphQLQuery(name = "foo")
int getFoo();
}
When attempting to transform the schema with Federation:
GraphQLSchema schema = new GraphQLSchemaGenerator()
.withBasePackages("org.example")
.withOperationsFromSingleton(myResolver)
.generate();
GraphQLSchema federatedSchema = Federation.transform(schema)
we'll see the above Exception
Caused by: java.lang.ClassCastException: class java.lang.String cannot be cast to class graphql.language.StringValue (java.lang.String is in module java.base of loader 'bootstrap'; graphql.language.StringValue is in unnamed module of loader 'app')
at com.apollographql.federation.graphqljava.SchemaTransformer.lambda$retrieveFieldSets$11(SchemaTransformer.java:189)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.Collections$2.tryAdvance(Collections.java:4820)
at java.base/java.util.Collections$2.forEachRemaining(Collections.java:4828)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
at com.apollographql.federation.graphqljava.SchemaTransformer.retrieveFieldSets(SchemaTransformer.java:191)
at com.apollographql.federation.graphqljava.SchemaTransformer.lambda$getFederatedEntities$6(SchemaTransformer.java:153)
at graphql.com.google.common.collect.ImmutableList.forEach(ImmutableList.java:422)
at com.apollographql.federation.graphqljava.SchemaTransformer.lambda$getFederatedEntities$7(SchemaTransformer.java:149)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
at com.apollographql.federation.graphqljava.SchemaTransformer.getFederatedEntities(SchemaTransformer.java:146)
at com.apollographql.federation.graphqljava.SchemaTransformer.build(SchemaTransformer.java:89)
at org.example.GraphQlController.<init>(GraphQlController.java:35)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:204)
A minimal example project which is replicating the issue is attached.
Metadata
Metadata
Assignees
Labels
No labels