Skip to content

Commit 7ddb1a9

Browse files
committed
ConnectionDataFetcher supports DataFetcherResult
Closes gh-835
1 parent 80b1c27 commit 7ddb1a9

File tree

2 files changed

+55
-34
lines changed

2 files changed

+55
-34
lines changed

spring-graphql/src/main/java/org/springframework/graphql/data/pagination/ConnectionFieldTypeVisitor.java

+18-4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.concurrent.CompletionStage;
2424

2525
import graphql.TrivialDataFetcher;
26+
import graphql.execution.DataFetcherResult;
2627
import graphql.relay.Connection;
2728
import graphql.relay.DefaultConnection;
2829
import graphql.relay.DefaultConnectionCursor;
@@ -189,17 +190,30 @@ private record ConnectionDataFetcher(DataFetcher<?> delegate, ConnectionAdapter
189190
public Object get(DataFetchingEnvironment environment) throws Exception {
190191
Object result = this.delegate.get(environment);
191192
if (result instanceof Mono<?> mono) {
192-
return mono.map(this::adapt);
193+
return mono.map(this::adaptDataFetcherResult);
193194
}
194195
else if (result instanceof CompletionStage<?> stage) {
195-
return stage.thenApply(this::adapt);
196+
return stage.thenApply(this::adaptDataFetcherResult);
196197
}
197198
else {
198-
return adapt(result);
199+
return adaptDataFetcherResult(result);
199200
}
200201
}
201202

202-
private <T> Object adapt(@Nullable Object container) {
203+
private Object adaptDataFetcherResult(@Nullable Object value) {
204+
if (value instanceof DataFetcherResult<?> dataFetcherResult) {
205+
Object adapted = adaptDataContainer(dataFetcherResult.getData());
206+
return DataFetcherResult.newResult()
207+
.data(adapted)
208+
.errors(dataFetcherResult.getErrors())
209+
.localContext(dataFetcherResult.getLocalContext()).build();
210+
}
211+
else {
212+
return adaptDataContainer(value);
213+
}
214+
}
215+
216+
private <T> Object adaptDataContainer(@Nullable Object container) {
203217
if (container == null) {
204218
return EMPTY_CONNECTION;
205219
}

spring-graphql/src/test/java/org/springframework/graphql/data/pagination/ConnectionFieldTypeVisitorTests.java

+37-30
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818

1919
import java.util.Collection;
2020
import java.util.List;
21+
import java.util.function.Consumer;
2122

23+
import graphql.execution.DataFetcherResult;
2224
import graphql.schema.DataFetcher;
2325
import graphql.schema.FieldCoordinates;
2426
import graphql.schema.GraphQLFieldDefinition;
@@ -52,36 +54,41 @@ public class ConnectionFieldTypeVisitorTests {
5254

5355

5456
@Test
55-
void paginatedTypeIsAdapted() {
56-
57-
ListConnectionAdapter adapter = new ListConnectionAdapter();
58-
adapter.setInitialOffset(30);
59-
adapter.setHasNext(true);
60-
61-
Mono<ExecutionGraphQlResponse> response = GraphQlSetup.schemaResource(BookSource.paginationSchema)
62-
.dataFetcher("Query", "books", env -> BookSource.books())
63-
.connectionSupport(adapter)
64-
.toGraphQlService()
65-
.execute(BookSource.booksConnectionQuery(null));
66-
67-
ResponseHelper.forResponse(response).assertData(
68-
"{\"books\":{" +
69-
"\"edges\":[" +
70-
"{\"cursor\":\"O_30\",\"node\":{\"id\":\"1\",\"name\":\"Nineteen Eighty-Four\"}}," +
71-
"{\"cursor\":\"O_31\",\"node\":{\"id\":\"2\",\"name\":\"The Great Gatsby\"}}," +
72-
"{\"cursor\":\"O_32\",\"node\":{\"id\":\"3\",\"name\":\"Catch-22\"}}," +
73-
"{\"cursor\":\"O_33\",\"node\":{\"id\":\"4\",\"name\":\"To The Lighthouse\"}}," +
74-
"{\"cursor\":\"O_34\",\"node\":{\"id\":\"5\",\"name\":\"Animal Farm\"}}," +
75-
"{\"cursor\":\"O_35\",\"node\":{\"id\":\"53\",\"name\":\"Breaking Bad\"}}," +
76-
"{\"cursor\":\"O_36\",\"node\":{\"id\":\"42\",\"name\":\"Hitchhiker's Guide to the Galaxy\"}}" +
77-
"]," +
78-
"\"pageInfo\":{" +
79-
"\"startCursor\":\"O_30\"," +
80-
"\"endCursor\":\"O_36\"," +
81-
"\"hasPreviousPage\":true," +
82-
"\"hasNextPage\":true}" +
83-
"}}"
84-
);
57+
void adaptPaginatedType() {
58+
59+
Consumer<DataFetcher<Object>> testConsumer = booksDataFetcher -> {
60+
ListConnectionAdapter adapter = new ListConnectionAdapter();
61+
adapter.setInitialOffset(30);
62+
adapter.setHasNext(true);
63+
64+
Mono<ExecutionGraphQlResponse> response = GraphQlSetup.schemaResource(BookSource.paginationSchema)
65+
.dataFetcher("Query", "books", booksDataFetcher)
66+
.connectionSupport(adapter)
67+
.toGraphQlService()
68+
.execute(BookSource.booksConnectionQuery(null));
69+
70+
ResponseHelper.forResponse(response).assertData(
71+
"{\"books\":{" +
72+
"\"edges\":[" +
73+
"{\"cursor\":\"O_30\",\"node\":{\"id\":\"1\",\"name\":\"Nineteen Eighty-Four\"}}," +
74+
"{\"cursor\":\"O_31\",\"node\":{\"id\":\"2\",\"name\":\"The Great Gatsby\"}}," +
75+
"{\"cursor\":\"O_32\",\"node\":{\"id\":\"3\",\"name\":\"Catch-22\"}}," +
76+
"{\"cursor\":\"O_33\",\"node\":{\"id\":\"4\",\"name\":\"To The Lighthouse\"}}," +
77+
"{\"cursor\":\"O_34\",\"node\":{\"id\":\"5\",\"name\":\"Animal Farm\"}}," +
78+
"{\"cursor\":\"O_35\",\"node\":{\"id\":\"53\",\"name\":\"Breaking Bad\"}}," +
79+
"{\"cursor\":\"O_36\",\"node\":{\"id\":\"42\",\"name\":\"Hitchhiker's Guide to the Galaxy\"}}" +
80+
"]," +
81+
"\"pageInfo\":{" +
82+
"\"startCursor\":\"O_30\"," +
83+
"\"endCursor\":\"O_36\"," +
84+
"\"hasPreviousPage\":true," +
85+
"\"hasNextPage\":true}" +
86+
"}}"
87+
);
88+
};
89+
90+
testConsumer.accept(env -> BookSource.books());
91+
testConsumer.accept(env -> DataFetcherResult.newResult().data(BookSource.books()).build());
8592
}
8693

8794
@Test // gh-709

0 commit comments

Comments
 (0)