Skip to content

Commit 9066c40

Browse files
committed
Fix issue returning CompletableFuture
Closes gh-628
1 parent 3586ede commit 9066c40

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetcherHandlerMethod.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
1616
package org.springframework.graphql.data.method.annotation.support;
1717

1818
import java.util.Arrays;
19+
import java.util.concurrent.CompletableFuture;
1920
import java.util.concurrent.Executor;
2021

2122
import graphql.schema.DataFetchingEnvironment;
@@ -133,11 +134,14 @@ public Object invoke(DataFetchingEnvironment environment) {
133134
}) :
134135
toArgsMono(args).flatMap(argValues -> {
135136
Object result = validateAndInvoke(argValues, environment);
136-
if (result instanceof Mono) {
137+
if (result instanceof Mono<?>) {
137138
return (Mono<?>) result;
138139
}
139-
else if (result instanceof Flux) {
140-
return Flux.from((Flux<?>) result).collectList();
140+
else if (result instanceof Flux<?>) {
141+
return ((Flux<?>) result).collectList();
142+
}
143+
else if (result instanceof CompletableFuture<?>) {
144+
return Mono.fromFuture((CompletableFuture<?>) result);
141145
}
142146
else {
143147
return Mono.justOrEmpty(result);

spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataFetcherHandlerMethodTests.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
2626
import graphql.schema.DataFetchingEnvironmentImpl;
2727
import org.junit.jupiter.api.Test;
2828
import org.mockito.Mockito;
29+
import reactor.core.publisher.Mono;
2930

3031
import org.springframework.core.task.SimpleAsyncTaskExecutor;
3132
import org.springframework.graphql.data.GraphQlArgumentBinder;
@@ -35,6 +36,8 @@
3536
import org.springframework.graphql.data.method.annotation.Argument;
3637
import org.springframework.graphql.data.method.annotation.QueryMapping;
3738
import org.springframework.lang.Nullable;
39+
import org.springframework.security.core.annotation.AuthenticationPrincipal;
40+
import org.springframework.security.core.userdetails.User;
3841
import org.springframework.util.ClassUtils;
3942

4043
import static org.assertj.core.api.Assertions.assertThat;
@@ -86,6 +89,23 @@ void callableReturnValue() throws Exception {
8689
assertThat(future.get()).isEqualTo("A");
8790
}
8891

92+
@Test
93+
void completableFutureReturnValue() {
94+
95+
HandlerMethodArgumentResolverComposite resolvers = new HandlerMethodArgumentResolverComposite();
96+
resolvers.addResolver(new AuthenticationPrincipalArgumentResolver((beanName, context) -> null));
97+
resolvers.addResolver(new ArgumentMethodArgumentResolver(new GraphQlArgumentBinder()));
98+
99+
DataFetcherHandlerMethod handlerMethod = new DataFetcherHandlerMethod(
100+
handlerMethodFor(new TestController(), "handleAndReturnFuture"), resolvers,
101+
null, null, false);
102+
103+
Object result = handlerMethod.invoke(DataFetchingEnvironmentImpl.newDataFetchingEnvironment().build());
104+
105+
assertThat(result).isInstanceOf(Mono.class);
106+
assertThat(((Mono<String>) result).block()).isEqualTo("B");
107+
}
108+
89109
private static HandlerMethod handlerMethodFor(Object controller, String methodName) {
90110
Method method = ClassUtils.getMethod(controller.getClass(), methodName, (Class<?>[]) null);
91111
return new HandlerMethod(controller, method);
@@ -112,6 +132,10 @@ public Callable<String> handleAndReturnCallable() {
112132
return () -> "A";
113133
}
114134

135+
public CompletableFuture<String> handleAndReturnFuture(@AuthenticationPrincipal User user) {
136+
return CompletableFuture.completedFuture("B");
137+
}
138+
115139
}
116140

117141
}

0 commit comments

Comments
 (0)