-
Notifications
You must be signed in to change notification settings - Fork 174
Closed
Description
I'm trying to use a batched resolver with arguments that implements pagination with cursors for the batchedComments property in the following graphql schema:
type Book {
id: Long
title: String
author: Author
isbn: String
comments(after: String, limit: Long): CommentsConnection
batchedComments(after: String, limit: Long): CommentsConnection
}
type Comment {
id: Long
text: String
}
type Author {
id: Long
name: String
}
input BookFilter {
title: String
}
type CommentsConnection {
edges: [CommentEdge]
pageInfo: PageInfo
}
type CommentEdge {
node: Comment
cursor: String
}
type PageInfo {
startCursor: String
endCursor: String
hasNextPage: Boolean
}
type Query {
books: [Book]!
findBooks(filter: BookFilter): [Book]!
authors: [Author]!
author(id: Long): Author!
}
type Mutation {
addBook(title: String, author: Long): Book
}
schema {
query: Query
mutation: Mutation
}
This is my resolver:
public class BookResolver implements GraphQLResolver<Book> {
private LibraryRepository libraryRespository;
public BookResolver(LibraryRepository libraryRespository) {
this.libraryRespository = libraryRespository;
}
public String getIsbn(Book book) {
return UUID.randomUUID().toString();
}
public CommentsConnection getComments(Book book, String after, Long limit) {
Long idAfter = null;
Long limitPlusOne = null;
if (after != null) {
idAfter = CommentEdge.fromGlobalId(after);
}
if (limit != null && limit < Long.MAX_VALUE) {
limitPlusOne = limit + 1;
}
List<Comment> commentsPlusOne = libraryRespository.findComments(book.getId(), idAfter, limitPlusOne);
Stream<Comment> stream = commentsPlusOne.stream();
if (limit != null) {
stream = stream.limit(limit);
}
List<Comment> comments = stream.collect(Collectors.toList());
Comment firstComment = (!comments.isEmpty()) ? comments.get(0) : null;
Comment lastComment = (!comments.isEmpty()) ? comments.get(comments.size() - 1) : null;
String startCursor = (firstComment != null) ? CommentEdge.toGlobalId(firstComment) : null;
String endCursor = (lastComment != null) ? CommentEdge.toGlobalId(lastComment) : null;
boolean hasNextPage = commentsPlusOne.size() > comments.size();
return new CommentsConnection(comments, new PageInfo(startCursor, endCursor, hasNextPage));
}
@Batched
public List<CommentsConnection> getBatchedComments(List<Book> books, List<String> after, List<Long> limit) {
List<CommentsConnection> ccs = new ArrayList<>();
for (int i = 0; i < books.size(); ++i) {
CommentsConnection cc = getComments(books.get(i), null, null);
ccs.add(cc);
}
return ccs;
}
}
But when I do this request I get an exception:
$ curl -XPOST -H "Content-Type: application/json" -d '{"query": "query Books{books{title isbn batchedComments(limit:1){edges{node{text}}}}}"}' http://localhost:8080/library
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of VALUE_NUMBER_INT token
at [Source: N/A; line: -1, column: -1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.DeserializationContext.reportMappingException(DeserializationContext.java:1234) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1122) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1075) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.handleNonArray(CollectionDeserializer.java:338) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:269) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:259) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:26) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3600) ~[jackson-databind-2.8.10.jar:2.8.10]
... 74 common frames omitted
Maybe I would expect the batched resolver signature was this instead:
@Batched
public List<CommentsConnection> getBatchedComments(List<Book> books, String after, Long limit)
But with this resolver signature on application start throws this exception:
Caused by: com.coxautodev.graphql.tools.SchemaClassScannerError: Unable to match type definition (TypeName{name='String'}) with java type (class java.lang.String): Method was marked as @Batched but parameter was not a list!
at com.coxautodev.graphql.tools.TypeClassMatcher.error(TypeClassMatcher.kt:22) ~[graphql-java-tools-4.3.0.jar:na]
at com.coxautodev.graphql.tools.TypeClassMatcher.stripBatchedType(TypeClassMatcher.kt:99) ~[graphql-java-tools-4.3.0.jar:na]
at com.coxautodev.graphql.tools.TypeClassMatcher.match(TypeClassMatcher.kt:26) ~[graphql-java-tools-4.3.0.jar:na]
at com.coxautodev.graphql.tools.SchemaClassScanner.scanResolverInfoForPotentialMatches(SchemaClassScanner.kt:215) ~[graphql-java-tools-4.3.0.jar:na]
at com.coxautodev.graphql.tools.SchemaClassScanner.scanQueueItemForPotentialMatches(SchemaClassScanner.kt:206) ~[graphql-java-tools-4.3.0.jar:na]
at com.coxautodev.graphql.tools.SchemaClassScanner.scanQueue(SchemaClassScanner.kt:103) ~[graphql-java-tools-4.3.0.jar:na]
at com.coxautodev.graphql.tools.SchemaClassScanner.scanForClasses(SchemaClassScanner.kt:81) ~[graphql-java-tools-4.3.0.jar:na]
at com.coxautodev.graphql.tools.SchemaParserBuilder.scan(SchemaParserBuilder.kt:149) ~[graphql-java-tools-4.3.0.jar:na]
at com.coxautodev.graphql.tools.SchemaParserBuilder.build(SchemaParserBuilder.kt:155) ~[graphql-java-tools-4.3.0.jar:na]
at io.github.picodotdev.blogbitix.graphql.Main.graphQLServletRegistrationBean(Main.java:42) [main/:na]
The full source code with a spring boot example is here: https://github.com/picodotdev/blog-ejemplos/tree/master/GraphQL
How I can use a batched resolver with arguments? Is it possible?
Metadata
Metadata
Assignees
Labels
No labels