Skip to content

Commit b847480

Browse files
committed
Adding additional configuration for Connections to fetch data asynchronously
1 parent 82a92dd commit b847480

File tree

6 files changed

+66
-12
lines changed

6 files changed

+66
-12
lines changed

src/main/java/graphql/annotations/connection/GraphQLConnection.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,11 @@
5252
* @return a connection validator
5353
*/
5454
Class <? extends ConnectionValidator> validator() default PaginatedDataConnectionTypeValidator.class;
55+
56+
/**
57+
* By default, the paginated data is fetched synchronously. If explicitly specified, asynchronous data fetching
58+
* will be used.
59+
* @return if async fetching to be used.
60+
*/
61+
boolean async() default false;
5562
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* Copyright 2016 Yurii Rashkovskii
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
*/
15+
package graphql.annotations.dataFetchers.connection;
16+
17+
import graphql.schema.DataFetcher;
18+
import graphql.schema.DataFetchingEnvironment;
19+
20+
import java.util.concurrent.CompletableFuture;
21+
22+
import static java.util.concurrent.CompletableFuture.supplyAsync;
23+
24+
public class AsyncConnectionDataFetcher<T> implements DataFetcher<CompletableFuture<graphql.relay.Connection<T>>> {
25+
private final ConnectionDataFetcher connectionDataFetcher;
26+
27+
@SuppressWarnings("unchecked")
28+
public AsyncConnectionDataFetcher(ConnectionDataFetcher connectionFetcher) {
29+
this.connectionDataFetcher = connectionFetcher;
30+
}
31+
32+
@Override
33+
public CompletableFuture<graphql.relay.Connection<T>> get(DataFetchingEnvironment environment) {
34+
return supplyAsync(() -> connectionDataFetcher.get(environment));
35+
}
36+
}

src/main/java/graphql/annotations/dataFetchers/connection/ConnectionDataFetcher.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,10 @@
2121
import java.lang.reflect.Constructor;
2222
import java.util.Arrays;
2323
import java.util.Optional;
24-
import java.util.concurrent.CompletableFuture;
2524

2625
import static graphql.annotations.processor.util.ReflectionKit.constructNewInstance;
27-
import static java.util.concurrent.CompletableFuture.supplyAsync;
2826

29-
public class ConnectionDataFetcher<T> implements DataFetcher<CompletableFuture<graphql.relay.Connection<T>>> {
27+
public class ConnectionDataFetcher<T> implements DataFetcher<graphql.relay.Connection<T>> {
3028
private final DataFetcher<?> actualDataFetcher;
3129
private final Constructor<ConnectionFetcher<T>> constructor;
3230

@@ -46,8 +44,8 @@ public ConnectionDataFetcher(Class<? extends ConnectionFetcher<T>> connection, D
4644
}
4745

4846
@Override
49-
public CompletableFuture<graphql.relay.Connection<T>> get(DataFetchingEnvironment environment) {
47+
public graphql.relay.Connection<T> get(DataFetchingEnvironment environment) {
5048
ConnectionFetcher<T> conn = constructNewInstance(constructor, actualDataFetcher);
51-
return supplyAsync(() -> conn.get(environment));
49+
return conn.get(environment);
5250
}
5351
}

src/main/java/graphql/annotations/processor/retrievers/fieldBuilders/field/FieldDataFetcherBuilder.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,20 @@
1919
import graphql.annotations.connection.GraphQLConnection;
2020
import graphql.annotations.dataFetchers.ExtensionDataFetcherWrapper;
2121
import graphql.annotations.dataFetchers.MethodDataFetcher;
22-
import graphql.annotations.dataFetchers.connection.ConnectionDataFetcher;
2322
import graphql.annotations.processor.ProcessingElementsContainer;
2423
import graphql.annotations.processor.retrievers.fieldBuilders.Builder;
2524
import graphql.annotations.processor.typeFunctions.TypeFunction;
2625
import graphql.annotations.processor.util.DataFetcherConstructor;
27-
import graphql.schema.*;
26+
import graphql.schema.DataFetcher;
27+
import graphql.schema.GraphQLNonNull;
28+
import graphql.schema.GraphQLType;
29+
import graphql.schema.PropertyDataFetcher;
2830

2931
import java.lang.reflect.Field;
3032
import java.lang.reflect.Method;
3133

3234
import static graphql.Scalars.GraphQLBoolean;
35+
import static graphql.annotations.processor.util.ConnectionUtil.getConnectionDataFetcher;
3336
import static java.util.Objects.nonNull;
3437

3538
public class FieldDataFetcherBuilder implements Builder<DataFetcher> {
@@ -61,9 +64,8 @@ public DataFetcher build() {
6164
actualDataFetcher = handleNullCase(actualDataFetcher);
6265
}
6366

64-
6567
if (isConnection) {
66-
actualDataFetcher = new ConnectionDataFetcher(field.getAnnotation(GraphQLConnection.class).connection(), actualDataFetcher);
68+
actualDataFetcher = getConnectionDataFetcher(field.getAnnotation(GraphQLConnection.class), actualDataFetcher);
6769
}
6870
return actualDataFetcher;
6971
}
@@ -75,7 +77,7 @@ private DataFetcher handleNullCase(DataFetcher actualDataFetcher) {
7577
actualDataFetcher = getBooleanDataFetcher(actualDataFetcher);
7678
} else if (checkIfPrefixGetterExists(field.getDeclaringClass(), "get", field.getName())) {
7779
actualDataFetcher = wrapExtension(new PropertyDataFetcher(field.getName()), field);
78-
} else{
80+
} else {
7981
actualDataFetcher = getDataFetcherWithFluentGetter(actualDataFetcher);
8082
}
8183

src/main/java/graphql/annotations/processor/retrievers/fieldBuilders/method/MethodDataFetcherBuilder.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import graphql.annotations.dataFetchers.BatchedMethodDataFetcher;
2222
import graphql.annotations.dataFetchers.MethodDataFetcher;
2323
import graphql.annotations.dataFetchers.RelayMutationMethodDataFetcher;
24-
import graphql.annotations.dataFetchers.connection.ConnectionDataFetcher;
2524
import graphql.annotations.processor.ProcessingElementsContainer;
2625
import graphql.annotations.processor.retrievers.fieldBuilders.Builder;
2726
import graphql.annotations.processor.typeFunctions.TypeFunction;
@@ -34,6 +33,8 @@
3433
import java.lang.reflect.Method;
3534
import java.util.List;
3635

36+
import static graphql.annotations.processor.util.ConnectionUtil.getConnectionDataFetcher;
37+
3738
public class MethodDataFetcherBuilder implements Builder<DataFetcher> {
3839
private Method method;
3940
private GraphQLOutputType outputType;
@@ -74,7 +75,7 @@ public DataFetcher build() {
7475
}
7576

7677
if (isConnection){
77-
actualDataFetcher = new ConnectionDataFetcher(method.getAnnotation(GraphQLConnection.class).connection(), actualDataFetcher);
78+
actualDataFetcher = getConnectionDataFetcher(method.getAnnotation(GraphQLConnection.class), actualDataFetcher);
7879
}
7980
return actualDataFetcher;
8081
}

src/main/java/graphql/annotations/processor/util/ConnectionUtil.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
import graphql.annotations.connection.ConnectionValidator;
1818
import graphql.annotations.connection.GraphQLConnection;
19+
import graphql.annotations.dataFetchers.connection.AsyncConnectionDataFetcher;
20+
import graphql.annotations.dataFetchers.connection.ConnectionDataFetcher;
1921
import graphql.schema.*;
2022

2123
import java.lang.reflect.AccessibleObject;
@@ -45,4 +47,12 @@ public static boolean isConnection(AccessibleObject obj, GraphQLType type) {
4547
}
4648
}
4749

50+
public static DataFetcher getConnectionDataFetcher(GraphQLConnection connectionAnnotation, DataFetcher actualDataFetcher) {
51+
actualDataFetcher = new ConnectionDataFetcher(connectionAnnotation.connection(), actualDataFetcher);
52+
if (connectionAnnotation.async()) {
53+
actualDataFetcher = new AsyncConnectionDataFetcher((ConnectionDataFetcher) actualDataFetcher);
54+
}
55+
return actualDataFetcher;
56+
}
57+
4858
}

0 commit comments

Comments
 (0)