From 4078799e341b42cd29c23154ca734cb25b358d33 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 20 Jul 2021 13:42:26 +0100 Subject: [PATCH] Auto-register Querydsl DataFetcher's only for top-level queries Closes gh-93 --- ...raphQlWebFluxQuerydslAutoConfiguration.java | 4 +++- ...GraphQlWebMvcQuerydslAutoConfiguration.java | 4 +++- .../graphql/data/QuerydslDataFetcher.java | 18 ++++++++++++++---- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/data/GraphQlWebFluxQuerydslAutoConfiguration.java b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/data/GraphQlWebFluxQuerydslAutoConfiguration.java index 2a4659b5..63cc14ec 100644 --- a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/data/GraphQlWebFluxQuerydslAutoConfiguration.java +++ b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/data/GraphQlWebFluxQuerydslAutoConfiguration.java @@ -40,10 +40,12 @@ import org.springframework.graphql.execution.GraphQlSource; /** * {@link EnableAutoConfiguration Auto-configuration} that creates a * {@link GraphQlSourceBuilderCustomizer}s to detect Spring Data repositories - * with Querydsl support and register them as {@code DataFetcher}s. + * with Querydsl support and register them as {@code DataFetcher}s for any + * queries with a matching return type. * * @author Rossen Stoyanchev * @since 1.0.0 + * @see QuerydslDataFetcher#registrationTypeVisitor(List, List) */ @Configuration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) diff --git a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/data/GraphQlWebMvcQuerydslAutoConfiguration.java b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/data/GraphQlWebMvcQuerydslAutoConfiguration.java index e056d923..530788ce 100644 --- a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/data/GraphQlWebMvcQuerydslAutoConfiguration.java +++ b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/data/GraphQlWebMvcQuerydslAutoConfiguration.java @@ -40,10 +40,12 @@ import org.springframework.graphql.execution.GraphQlSource; /** * {@link EnableAutoConfiguration Auto-configuration} that creates a * {@link GraphQlSourceBuilderCustomizer}s to detect Spring Data repositories - * with Querydsl support and register them as {@code DataFetcher}s. + * with Querydsl support and register them as {@code DataFetcher}s for any + * queries with a matching return type. * * @author Rossen Stoyanchev * @since 1.0.0 + * @see QuerydslDataFetcher#registrationTypeVisitor(List, List) */ @Configuration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/QuerydslDataFetcher.java b/spring-graphql/src/main/java/org/springframework/graphql/data/QuerydslDataFetcher.java index 1e2bde70..4067ec33 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/QuerydslDataFetcher.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/QuerydslDataFetcher.java @@ -161,9 +161,11 @@ public abstract class QuerydslDataFetcher { } /** - * Create a {@link GraphQLTypeVisitor} that finds fields whose type matches - * the domain type of the the given repositories and registers them as - * {@link DataFetcher}s. + * Create a {@link GraphQLTypeVisitor} that finds queries with a return type + * whose name matches to the domain type name of the given repositories and + * registers {@link DataFetcher}s for those queries. + *

Note: currently, this method will match only to + * queries under the top-level "Query" type in the GraphQL schema. * @param executors repositories to consider for registration * @param reactiveExecutors reactive repositories to consider for registration * @return the created visitor @@ -529,13 +531,21 @@ public abstract class QuerydslDataFetcher { public TraversalControl visitGraphQLFieldDefinition( GraphQLFieldDefinition fieldDefinition, TraverserContext context) { + if (this.executorMap.isEmpty()) { + return TraversalControl.QUIT; + } + GraphQLType fieldType = fieldDefinition.getType(); + GraphQLFieldsContainer parent = (GraphQLFieldsContainer) context.getParentNode(); + if (!parent.getName().equals("Query")) { + return TraversalControl.ABORT; + } + DataFetcher dataFetcher = (fieldType instanceof GraphQLList ? getDataFetcher(((GraphQLList) fieldType).getWrappedType(), false) : getDataFetcher(fieldType, true)); if (dataFetcher != null) { - GraphQLFieldsContainer parent = (GraphQLFieldsContainer) context.getParentNode(); GraphQLCodeRegistry.Builder registry = context.getVarFromParents(GraphQLCodeRegistry.Builder.class); if (!hasDataFetcher(registry, parent, fieldDefinition)) { registry.dataFetcher(parent, fieldDefinition, dataFetcher);