diff --git a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/GraphQlServiceAutoConfiguration.java b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/GraphQlServiceAutoConfiguration.java
index 6729dda5..ec436480 100644
--- a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/GraphQlServiceAutoConfiguration.java
+++ b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/GraphQlServiceAutoConfiguration.java
@@ -25,6 +25,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.graphql.GraphQlService;
+import org.springframework.graphql.execution.BatchLoaderRegistry;
+import org.springframework.graphql.execution.DefaultBatchLoaderRegistry;
import org.springframework.graphql.execution.ExecutionGraphQlService;
import org.springframework.graphql.execution.GraphQlSource;
@@ -41,10 +43,19 @@ import org.springframework.graphql.execution.GraphQlSource;
@AutoConfigureAfter(GraphQlAutoConfiguration.class)
public class GraphQlServiceAutoConfiguration {
+ private final DefaultBatchLoaderRegistry batchLoaderRegistry = new DefaultBatchLoaderRegistry();
+
+ @Bean
+ public BatchLoaderRegistry batchLoaderRegistry() {
+ return this.batchLoaderRegistry;
+ }
+
@Bean
@ConditionalOnMissingBean
public GraphQlService graphQlService(GraphQlSource graphQlSource) {
- return new ExecutionGraphQlService(graphQlSource);
+ ExecutionGraphQlService service = new ExecutionGraphQlService(graphQlSource);
+ service.addDataLoaderRegistrar(this.batchLoaderRegistry);
+ return service;
}
}
diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/BatchLoaderRegistry.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/BatchLoaderRegistry.java
new file mode 100644
index 00000000..f33265c7
--- /dev/null
+++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/BatchLoaderRegistry.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2002-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.graphql.execution;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+
+import org.dataloader.BatchLoaderEnvironment;
+import org.dataloader.DataLoaderOptions;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+/**
+ * Registry of functions that batch load data values given a set of keys.
+ *
+ *
At request time, each function is registered as a
+ * {@link org.dataloader.DataLoader} in the {@link org.dataloader.DataLoaderRegistry}
+ * and can be accessed in the data layer to load related entities while avoiding
+ * the N+1 select problem.
+ *
+ * @author Rossen Stoyanchev
+ * @since 1.0.0
+ * @see Using DataLoader
+ * @see org.dataloader.BatchLoader
+ * @see org.dataloader.MappedBatchLoader
+ * @see org.dataloader.DataLoader
+ */
+public interface BatchLoaderRegistry {
+
+ /**
+ * Start the registration of a new function for batch loading data values by
+ * specifying the key and value types.
+ * @param keyType the type of the key that identifies the value
+ * @param valueType the type of the data value
+ * @param the key type
+ * @param the value type
+ * @return a spec to complete the registration
+ */
+ RegistrationSpec forTypePair(Class keyType, Class valueType);
+
+
+ /**
+ * Spec to complete the registration of a batch loading function.
+ *
+ * @param the type of the key that identifies the value
+ * @param the type of the data value
+ */
+ interface RegistrationSpec {
+
+ /**
+ * Customize the name under which the {@link org.dataloader.DataLoader}
+ * is registered and can be accessed in the data layer.
+ * By default, this is the full class name of the value type.
+ * @param name the name to use
+ * @return a spec to complete the registration
+ */
+ RegistrationSpec withName(String name);
+
+ /**
+ * Customize the {@link DataLoaderOptions} to use to create the
+ * {@link org.dataloader.DataLoader} via {@link org.dataloader.DataLoaderFactory}.
+ * @param optionsConsumer callback to customize the options, invoked
+ * immediately and given access to the options instance
+ * @return a spec to complete the registration
+ */
+ RegistrationSpec withOptions(Consumer optionsConsumer);
+
+ /**
+ * Replace the {@link DataLoaderOptions} to use to create the
+ * {@link org.dataloader.DataLoader} via {@link org.dataloader.DataLoaderFactory}.
+ * @param options the options to use
+ * @return a spec to complete the registration
+ */
+ RegistrationSpec withOptions(DataLoaderOptions options);
+
+ /**
+ * Register the give batch loading function.
+ * The values returned from the function must match the order and
+ * the number of keys, with {@code null} for missing values.
+ * Please, see {@link org.dataloader.BatchLoader}.
+ * @param loader the loader function
+ * @see org.dataloader.BatchLoader
+ */
+ void registerBatchLoader(BiFunction, BatchLoaderEnvironment, Flux> loader);
+
+ /**
+ * A variant of {@link #registerBatchLoader(BiFunction)} that returns a
+ * Map of key-value pairs, which is useful is there aren't values for all keys.
+ * Please see {@link org.dataloader.MappedBatchLoader}.
+ * @param loader the loader function
+ * @see org.dataloader.MappedBatchLoader
+ */
+ void registerMappedBatchLoader(BiFunction, BatchLoaderEnvironment, Mono