diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/ConnectionTypeGenerator.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/ConnectionTypeDefinitionConfigurer.java
similarity index 80%
rename from spring-graphql/src/main/java/org/springframework/graphql/execution/ConnectionTypeGenerator.java
rename to spring-graphql/src/main/java/org/springframework/graphql/execution/ConnectionTypeDefinitionConfigurer.java
index 6e2e1334..4d22fbcb 100644
--- a/spring-graphql/src/main/java/org/springframework/graphql/execution/ConnectionTypeGenerator.java
+++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/ConnectionTypeDefinitionConfigurer.java
@@ -17,7 +17,6 @@ package org.springframework.graphql.execution;
import java.util.LinkedHashSet;
import java.util.Set;
-import java.util.function.Function;
import java.util.stream.Collectors;
import graphql.language.FieldDefinition;
@@ -30,18 +29,20 @@ import graphql.language.TypeName;
import graphql.schema.idl.TypeDefinitionRegistry;
/**
- * Exposes the {@link #generateConnectionTypes(TypeDefinitionRegistry)
- * generateConnectionTypes method} for adding boilerplate type definitions to a
- * {@link TypeDefinitionRegistry}, for pagination based on the Relay
- * GraphQL Cursor Connections Specification.
+ * {@link TypeDefinitionConfigurer} that generates "Connection" types by looking
+ * for fields whose type definition name ends in "Connection", considered by the
+ * GraphQL Cursor Connections Specification
+ * to be a {@literal Connection Type}, and adding the required type definitions
+ * if they don't already exist.
*
- *
Use {@link GraphQlSource.SchemaResourceBuilder#configureTypeDefinitionRegistry(Function)}
- * to enable connection type generation.
+ *
This is intended to be set on
+ * {@link GraphQlSource.SchemaResourceBuilder#configureTypeDefinitions(TypeDefinitionConfigurer)
+ * GraphQlSource.Builder}.
*
* @author Rossen Stoyanchev
* @since 1.2
*/
-public class ConnectionTypeGenerator {
+public class ConnectionTypeDefinitionConfigurer implements TypeDefinitionConfigurer {
private static final TypeName STRING_TYPE = new TypeName("String");
@@ -50,14 +51,8 @@ public class ConnectionTypeGenerator {
private static final TypeName PAGE_INFO_TYPE = new TypeName("PageInfo");
- /**
- * Find fields whose type definition name ends in "Connection", considered
- * by the spec to be a {@literal Connection Type}, and add type definitions
- * for all such types, if they don't exist already.
- * @param registry the registry to check and add types to
- * @return the same registry instance with additional types added
- */
- public TypeDefinitionRegistry generateConnectionTypes(TypeDefinitionRegistry registry) {
+ @Override
+ public void configure(TypeDefinitionRegistry registry) {
Set typeNames = findConnectionTypeNames(registry);
@@ -89,8 +84,6 @@ public class ConnectionTypeGenerator {
.build());
});
}
-
- return registry;
}
private static Set findConnectionTypeNames(TypeDefinitionRegistry registry) {
diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultSchemaResourceGraphQlSourceBuilder.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultSchemaResourceGraphQlSourceBuilder.java
index 9c67a078..96a38e0d 100644
--- a/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultSchemaResourceGraphQlSourceBuilder.java
+++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultSchemaResourceGraphQlSourceBuilder.java
@@ -24,7 +24,6 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiFunction;
-import java.util.function.Function;
import java.util.stream.Collectors;
import graphql.language.InterfaceTypeDefinition;
@@ -61,8 +60,7 @@ final class DefaultSchemaResourceGraphQlSourceBuilder
private final Set schemaResources = new LinkedHashSet<>();
- @Nullable
- private Function typeDefinitionRegistryConfigurer;
+ private List typeDefinitionConfigurers = new ArrayList<>();
private final List runtimeWiringConfigurers = new ArrayList<>();
@@ -81,12 +79,8 @@ final class DefaultSchemaResourceGraphQlSourceBuilder
}
@Override
- public GraphQlSource.SchemaResourceBuilder configureTypeDefinitionRegistry(
- Function configurer) {
-
- this.typeDefinitionRegistryConfigurer = (this.typeDefinitionRegistryConfigurer != null ?
- this.typeDefinitionRegistryConfigurer.andThen(configurer) : configurer);
-
+ public GraphQlSource.SchemaResourceBuilder configureTypeDefinitions(TypeDefinitionConfigurer configurer) {
+ this.typeDefinitionConfigurers.add(configurer);
return this;
}
@@ -118,8 +112,8 @@ final class DefaultSchemaResourceGraphQlSourceBuilder
.reduce(TypeDefinitionRegistry::merge)
.orElseThrow(MissingSchemaException::new);
- if (this.typeDefinitionRegistryConfigurer != null) {
- registry = this.typeDefinitionRegistryConfigurer.apply(registry);
+ for (TypeDefinitionConfigurer configurer : this.typeDefinitionConfigurers) {
+ configurer.configure(registry);
}
logger.info("Loaded " + this.schemaResources.size() + " resource(s) in the GraphQL schema.");
diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/GraphQlSource.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/GraphQlSource.java
index f1db320f..8718f5bb 100644
--- a/spring-graphql/src/main/java/org/springframework/graphql/execution/GraphQlSource.java
+++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/GraphQlSource.java
@@ -173,17 +173,14 @@ public interface GraphQlSource {
SchemaResourceBuilder schemaResources(Resource... resources);
/**
- * Provide a function to customize the {@link TypeDefinitionRegistry}
- * created by parsing schema files. This allows adding or changing schema
- * type definitions before {@link GraphQLSchema} is created and validated.
- * @param configurer the function to apply accepting the current
- * {@link TypeDefinitionRegistry} and returning the one to use, likely
- * the same instance since {@link TypeDefinitionRegistry} is mutable.
+ * Customize the {@link TypeDefinitionRegistry} created from parsed
+ * schema files, adding or changing schema type definitions before the
+ * {@link GraphQLSchema} is created and validated.
+ * @param configurer the configurer to apply
* @return the current builder
- * @sine 1.2
+ * @since 1.2
*/
- SchemaResourceBuilder configureTypeDefinitionRegistry(
- Function configurer);
+ SchemaResourceBuilder configureTypeDefinitions(TypeDefinitionConfigurer configurer);
/**
* Configure the underlying {@link RuntimeWiring.Builder} to register
diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/TypeDefinitionConfigurer.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/TypeDefinitionConfigurer.java
new file mode 100644
index 00000000..ea71477d
--- /dev/null
+++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/TypeDefinitionConfigurer.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2002-2023 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 graphql.schema.GraphQLSchema;
+import graphql.schema.idl.TypeDefinitionRegistry;
+
+/**
+ * Callback that allows customizing the {@link TypeDefinitionRegistry} created
+ * from parsed schema files. It allows adding schema types programmatically
+ * before the registry is used to create {@link GraphQLSchema}.
+ *
+ * @author Rossen Stoyanchev
+ * @since 1.2
+ */
+public interface TypeDefinitionConfigurer {
+
+ /**
+ * Customize the given {@link TypeDefinitionRegistry}.
+ * @param registry the registry to customize
+ */
+ void configure(TypeDefinitionRegistry registry);
+
+}
diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPaginationTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPaginationTests.java
index e912eaee..877912f0 100644
--- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPaginationTests.java
+++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPaginationTests.java
@@ -35,7 +35,7 @@ import org.springframework.graphql.data.pagination.ConnectionFieldTypeVisitor;
import org.springframework.graphql.data.query.ScrollPositionCursorStrategy;
import org.springframework.graphql.data.query.ScrollSubrange;
import org.springframework.graphql.data.query.WindowConnectionAdapter;
-import org.springframework.graphql.execution.ConnectionTypeGenerator;
+import org.springframework.graphql.execution.ConnectionTypeDefinitionConfigurer;
import org.springframework.stereotype.Controller;
import static org.assertj.core.api.Assertions.assertThat;
@@ -83,8 +83,7 @@ public class SchemaMappingPaginationTests {
ExecutionGraphQlService graphQlService = graphQlService((configurer, setup) -> {
- ConnectionTypeGenerator typeGenerator = new ConnectionTypeGenerator();
- setup.typeDefinitionRegistryConfigurer(typeGenerator::generateConnectionTypes);
+ setup.typeDefinitionConfigurer(new ConnectionTypeDefinitionConfigurer());
ScrollPositionCursorStrategy cursorStrategy = new ScrollPositionCursorStrategy();
WindowConnectionAdapter connectionAdapter = new WindowConnectionAdapter(cursorStrategy);
diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/pagination/ConnectionFieldTypeVisitorTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/pagination/ConnectionFieldTypeVisitorTests.java
index 32c7bb1d..06c310ca 100644
--- a/spring-graphql/src/test/java/org/springframework/graphql/data/pagination/ConnectionFieldTypeVisitorTests.java
+++ b/spring-graphql/src/test/java/org/springframework/graphql/data/pagination/ConnectionFieldTypeVisitorTests.java
@@ -26,7 +26,7 @@ import org.springframework.graphql.BookSource;
import org.springframework.graphql.ExecutionGraphQlResponse;
import org.springframework.graphql.GraphQlSetup;
import org.springframework.graphql.TestExecutionRequest;
-import org.springframework.graphql.execution.ConnectionTypeGenerator;
+import org.springframework.graphql.execution.ConnectionTypeDefinitionConfigurer;
import static org.assertj.core.api.Assertions.assertThat;
@@ -75,7 +75,7 @@ public class ConnectionFieldTypeVisitorTests {
ExecutionGraphQlResponse response = GraphQlSetup.schemaContent(schemaContent)
.dataFetcher("Query", "books", env -> BookSource.books())
- .typeDefinitionRegistryConfigurer(new ConnectionTypeGenerator()::generateConnectionTypes)
+ .typeDefinitionConfigurer(new ConnectionTypeDefinitionConfigurer())
.typeVisitor(ConnectionFieldTypeVisitor.create(List.of(adapter)))
.toGraphQlService()
.execute(TestExecutionRequest.forDocument(document))
diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/ConnectionTypeGeneratorTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/ConnectionTypeDefinitionConfigurerTests.java
similarity index 93%
rename from spring-graphql/src/test/java/org/springframework/graphql/execution/ConnectionTypeGeneratorTests.java
rename to spring-graphql/src/test/java/org/springframework/graphql/execution/ConnectionTypeDefinitionConfigurerTests.java
index d5ab9dcc..2a908fc6 100644
--- a/spring-graphql/src/test/java/org/springframework/graphql/execution/ConnectionTypeGeneratorTests.java
+++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/ConnectionTypeDefinitionConfigurerTests.java
@@ -38,12 +38,12 @@ import org.springframework.graphql.TestExecutionRequest;
import static org.assertj.core.api.Assertions.assertThat;
/**
- * Unit tests for {@link ConnectionTypeGenerator}.
+ * Unit tests for {@link ConnectionTypeDefinitionConfigurer}.
*
* @author Rossen Stoyanchev
* @since 1.2
*/
-public class ConnectionTypeGeneratorTests {
+public class ConnectionTypeDefinitionConfigurerTests {
@Test
void connectionTypeGeneration() throws Exception {
@@ -108,8 +108,7 @@ public class ConnectionTypeGeneratorTests {
}
private GraphQlSetup initGraphQlSetup(String schema) {
- ConnectionTypeGenerator generator = new ConnectionTypeGenerator();
- return GraphQlSetup.schemaContent(schema).typeDefinitionRegistryConfigurer(generator::generateConnectionTypes);
+ return GraphQlSetup.schemaContent(schema).typeDefinitionConfigurer(new ConnectionTypeDefinitionConfigurer());
}
private static Connection createConnection(
diff --git a/spring-graphql/src/testFixtures/java/org/springframework/graphql/GraphQlSetup.java b/spring-graphql/src/testFixtures/java/org/springframework/graphql/GraphQlSetup.java
index 3e0a461f..98e4fc55 100644
--- a/spring-graphql/src/testFixtures/java/org/springframework/graphql/GraphQlSetup.java
+++ b/spring-graphql/src/testFixtures/java/org/springframework/graphql/GraphQlSetup.java
@@ -19,14 +19,12 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import java.util.function.Function;
import graphql.GraphQL;
import graphql.execution.instrumentation.Instrumentation;
import graphql.schema.DataFetcher;
import graphql.schema.GraphQLTypeVisitor;
import graphql.schema.TypeResolver;
-import graphql.schema.idl.TypeDefinitionRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ByteArrayResource;
@@ -38,6 +36,7 @@ import org.springframework.graphql.execution.DefaultExecutionGraphQlService;
import org.springframework.graphql.execution.GraphQlSource;
import org.springframework.graphql.execution.RuntimeWiringConfigurer;
import org.springframework.graphql.execution.SubscriptionExceptionResolver;
+import org.springframework.graphql.execution.TypeDefinitionConfigurer;
import org.springframework.graphql.server.WebGraphQlHandler;
import org.springframework.graphql.server.WebGraphQlInterceptor;
import org.springframework.graphql.server.WebGraphQlSetup;
@@ -82,10 +81,8 @@ public class GraphQlSetup implements GraphQlServiceSetup {
wiringBuilder.type(type, typeBuilder -> typeBuilder.dataFetcher(field, dataFetcher)));
}
- public GraphQlSetup typeDefinitionRegistryConfigurer(
- Function configurer) {
-
- this.graphQlSourceBuilder.configureTypeDefinitionRegistry(configurer);
+ public GraphQlSetup typeDefinitionConfigurer(TypeDefinitionConfigurer configurer) {
+ this.graphQlSourceBuilder.configureTypeDefinitions(configurer);
return this;
}