graphql-java-tools
graphql-java-tools copied to clipboard
Type dictionary for ListType
I'm trying to define some graphQL types dynamically using a typeDefinitionFactory and the fact that field values can be resolved using the Map.get()
method. It seems to be working fine as long as I don't have fields with list types. Here's a minimal example of the problem I bumped into:
public static class MyFooType {
public String bar;
}
public static class FooResolver extends HashMap<String, Object> implements GraphQLQueryResolver {
@Override
public Object get(Object key) {
if ("foo".equals(key))
return Arrays.asList(new MyFooType(), new MyFooType());
throw new IllegalArgumentException("unknown field " + key);
}
}
public static void main(String[] args) {
GraphQLSchema schema =
SchemaParser.newParser().schemaString("type Query{ foo: [FooType] } type FooType { bar: String }")
.resolvers(new FooResolver())
.dictionary("FooType", MyFooType.class)
.build().makeExecutableSchema();
System.out.println("OK!");
}
This causes an exception:
Exception in thread "main" graphql.kickstart.tools.SchemaClassScannerError: Unable to match type definition (ListType{type=TypeName{name='FooType'}}) with java type (java.lang.Object): Java class is not a List or generic type information was lost: class java.lang.Object
at graphql.kickstart.tools.TypeClassMatcher.error(TypeClassMatcher.kt:20)
at graphql.kickstart.tools.TypeClassMatcher.match(TypeClassMatcher.kt:78)
at graphql.kickstart.tools.TypeClassMatcher.match(TypeClassMatcher.kt:23)
at graphql.kickstart.tools.SchemaClassScanner.scanResolverInfoForPotentialMatches(SchemaClassScanner.kt:257)
...
I guess the problem could be that the framework doesn't know whether to expect a java.util.List
or a java array as the foo
value. Is there a way to pass this information?
I tried .dictionary("[FooType]", List.class)
, but that results in another exception:
Exception in thread "main" graphql.kickstart.tools.SchemaClassScannerError: Class in supplied dictionary 'java.util.List' specified type name '[FooType]', but a type definition with that name was not found!
at graphql.kickstart.tools.SchemaClassScanner.<init>(SchemaClassScanner.kt:53)
at graphql.kickstart.tools.SchemaParserBuilder.scan(SchemaParserBuilder.kt:153)
Did you solve it?
Nope, I had to add a wrapper class and declare an accessor method for each Collection<?>
value in the map, lots of boilerplate.
Closing this since it's old but here is a working example anyway:
@Test
fun `bing`() {
val schema = SchemaParser.newParser()
.schemaString(
"""
type Query{ foo: [FooType] }
type FooType { bar: String }
""")
.resolvers(FooResolver())
.dictionary("FooType", FooType::class.java)
.build().makeExecutableSchema()
}
private class FooResolver : GraphQLQueryResolver {
fun foo(): List<FooType> = listOf()
}
data class FooType(val bar: String = "")