Skip to content

Commit e00e10c

Browse files
committed
Use ReactiveAdapterRegistry for return type checks
See gh-991
1 parent 3ea4b38 commit e00e10c

File tree

2 files changed

+16
-37
lines changed

2 files changed

+16
-37
lines changed

spring-graphql/src/main/java/org/springframework/graphql/data/federation/FederationSchemaFactory.java

+11-11
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.util.LinkedHashMap;
2121
import java.util.List;
2222
import java.util.Map;
23-
import java.util.concurrent.CompletionStage;
2423
import java.util.function.BiFunction;
2524
import java.util.stream.Collectors;
2625

@@ -31,13 +30,13 @@
3130
import graphql.schema.TypeResolver;
3231
import graphql.schema.idl.RuntimeWiring;
3332
import graphql.schema.idl.TypeDefinitionRegistry;
34-
import reactor.core.publisher.Flux;
35-
import reactor.core.publisher.Mono;
3633

3734
import org.springframework.context.ApplicationContext;
3835
import org.springframework.context.expression.BeanFactoryResolver;
3936
import org.springframework.core.KotlinDetector;
4037
import org.springframework.core.MethodParameter;
38+
import org.springframework.core.ReactiveAdapter;
39+
import org.springframework.core.ReactiveAdapterRegistry;
4140
import org.springframework.core.annotation.AnnotatedElementUtils;
4241
import org.springframework.graphql.data.GraphQlArgumentBinder;
4342
import org.springframework.graphql.data.method.HandlerMethod;
@@ -188,15 +187,16 @@ public SchemaTransformer createSchemaTransformer(TypeDefinitionRegistry registry
188187
public record EntityMappingInfo(String typeName, HandlerMethod handlerMethod) {
189188

190189
public boolean isBatchHandlerMethod() {
191-
MethodParameter type = handlerMethod().getReturnType();
192-
Class<?> paramType = type.getParameterType();
193-
if (Flux.class.isAssignableFrom(paramType)) {
194-
return true;
190+
MethodParameter returnType = handlerMethod().getReturnType();
191+
Class<?> clazz = returnType.getParameterType();
192+
ReactiveAdapter adapter = ReactiveAdapterRegistry.getSharedInstance().getAdapter(clazz);
193+
if (adapter != null) {
194+
if (adapter.isMultiValue()) {
195+
return true;
196+
}
197+
returnType = returnType.nested();
195198
}
196-
if (Mono.class.isAssignableFrom(paramType) || CompletionStage.class.isAssignableFrom(paramType)) {
197-
type = type.nested();
198-
}
199-
return List.class.isAssignableFrom(type.getParameterType());
199+
return List.class.isAssignableFrom(returnType.getNestedParameterType());
200200
}
201201
}
202202

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

+5-26
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,6 @@
4545
import graphql.schema.GraphQLCodeRegistry;
4646
import graphql.schema.idl.RuntimeWiring;
4747
import graphql.schema.idl.TypeDefinitionRegistry;
48-
import kotlin.jvm.JvmClassMappingKt;
49-
import kotlin.reflect.KFunction;
50-
import kotlin.reflect.KType;
51-
import kotlin.reflect.full.KClassifiers;
52-
import kotlin.reflect.full.KTypes;
53-
import kotlin.reflect.jvm.ReflectJvmMapping;
54-
import kotlinx.coroutines.flow.Flow;
5548
import org.dataloader.DataLoader;
5649
import org.reactivestreams.Publisher;
5750
import reactor.core.publisher.Flux;
@@ -64,6 +57,8 @@
6457
import org.springframework.core.KotlinDetector;
6558
import org.springframework.core.MethodParameter;
6659
import org.springframework.core.ParameterNameDiscoverer;
60+
import org.springframework.core.ReactiveAdapter;
61+
import org.springframework.core.ReactiveAdapterRegistry;
6762
import org.springframework.core.ResolvableType;
6863
import org.springframework.core.annotation.AnnotatedElementUtils;
6964
import org.springframework.data.domain.ScrollPosition;
@@ -384,15 +379,15 @@ private DataFetcher<Object> registerBatchLoader(DataFetcherMappingInfo info) {
384379
clazz = returnType.getNestedParameterType();
385380
}
386381

387-
if (clazz.equals(Flux.class) || Collection.class.isAssignableFrom(clazz) ||
388-
(KotlinDetector.isSuspendingFunction(method) && KotlinDelegate.isFlowReturnType(method))) {
382+
ReactiveAdapter adapter = ReactiveAdapterRegistry.getSharedInstance().getAdapter(clazz);
389383

384+
if (Collection.class.isAssignableFrom(clazz) || (adapter != null && adapter.isMultiValue())) {
390385
registration.registerBatchLoader(invocable::invokeForIterable);
391386
ResolvableType valueType = ResolvableType.forMethodParameter(returnType.nested());
392387
return new BatchMappingDataFetcher(info, valueType, dataLoaderKey);
393388
}
394389

395-
if (clazz.equals(Mono.class)) {
390+
if (adapter != null) {
396391
returnType = returnType.nested();
397392
clazz = returnType.getNestedParameterType();
398393
}
@@ -672,20 +667,4 @@ Set<DataFetcherMappingInfo> removeExplicitMappings(
672667
}
673668
}
674669

675-
676-
/**
677-
* Inner class to avoid a hard dependency on Kotlin at runtime.
678-
*/
679-
private static final class KotlinDelegate {
680-
681-
private static final KType flowType =
682-
KClassifiers.getStarProjectedType(JvmClassMappingKt.getKotlinClass(Flow.class));
683-
684-
static boolean isFlowReturnType(Method method) {
685-
KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method);
686-
return (function != null && KTypes.isSubtypeOf(function.getReturnType(), flowType));
687-
}
688-
689-
}
690-
691670
}

0 commit comments

Comments
 (0)