Auto-configure TypeDefinitionConfigurer beans

Prior to this commit, the GraphQL auto-configuration would consider many
bean types like `DataFetcherExceptionResolver` and
`SubscriptionExceptionResolver` to configure the `GraphQlSource`.
It would also configure a default `ConnectionTypeDefinitionConfigurer`.

This commit will detect all `TypeDefinitionConfigurer` beans defined in
the application and configure them in addition to the
`ConnectionTypeDefinitionConfigurer`.

Closes gh-39118
This commit is contained in:
Brian Clozel 2024-01-15 18:22:37 +01:00
parent b79d1cef7d
commit e58f65366c
2 changed files with 36 additions and 2 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 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.
@ -66,6 +66,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;
/**
* {@link EnableAutoConfiguration Auto-configuration} for creating a Spring GraphQL base
@ -95,7 +96,8 @@ public class GraphQlAutoConfiguration {
ObjectProvider<DataFetcherExceptionResolver> exceptionResolvers,
ObjectProvider<SubscriptionExceptionResolver> subscriptionExceptionResolvers,
ObjectProvider<Instrumentation> instrumentations, ObjectProvider<RuntimeWiringConfigurer> wiringConfigurers,
ObjectProvider<GraphQlSourceBuilderCustomizer> sourceCustomizers) {
ObjectProvider<GraphQlSourceBuilderCustomizer> sourceCustomizers,
ObjectProvider<TypeDefinitionConfigurer> typeDefinitionConfigurers) {
String[] schemaLocations = properties.getSchema().getLocations();
Resource[] schemaResources = resolveSchemaResources(resourcePatternResolver, schemaLocations,
properties.getSchema().getFileExtensions());
@ -110,6 +112,7 @@ public class GraphQlAutoConfiguration {
if (!properties.getSchema().getIntrospection().isEnabled()) {
builder.configureRuntimeWiring(this::enableIntrospection);
}
typeDefinitionConfigurers.forEach(builder::configureTypeDefinitions);
builder.configureTypeDefinitions(new ConnectionTypeDefinitionConfigurer());
wiringConfigurers.orderedStream().forEach(builder::configureRuntimeWiring);
sourceCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));

View File

@ -26,6 +26,7 @@ import graphql.schema.GraphQLObjectType;
import graphql.schema.GraphQLOutputType;
import graphql.schema.GraphQLSchema;
import graphql.schema.idl.RuntimeWiring;
import graphql.schema.idl.TypeDefinitionRegistry;
import graphql.schema.visibility.DefaultGraphqlFieldVisibility;
import graphql.schema.visibility.NoIntrospectionGraphqlFieldVisibility;
import org.assertj.core.api.InstanceOfAssertFactories;
@ -52,6 +53,7 @@ import org.springframework.graphql.execution.DataFetcherExceptionResolver;
import org.springframework.graphql.execution.DataLoaderRegistrar;
import org.springframework.graphql.execution.GraphQlSource;
import org.springframework.graphql.execution.RuntimeWiringConfigurer;
import org.springframework.graphql.execution.TypeDefinitionConfigurer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@ -222,6 +224,14 @@ class GraphQlAutoConfigurationTests {
});
}
@Test
void shouldUseCustomTypeDefinitionConfigurerWhenDefined() {
this.contextRunner.withUserConfiguration(CustomTypeDefinitionConfigurer.class).run((context) -> {
TestTypeDefinitionConfigurer configurer = context.getBean(TestTypeDefinitionConfigurer.class);
assertThat(configurer.applied).isTrue();
});
}
@Test
void whenApplicationTaskExecutorIsDefinedThenAnnotatedControllerConfigurerShouldUseIt() {
this.contextRunner.withConfiguration(AutoConfigurations.of(TaskExecutionAutoConfiguration.class))
@ -337,4 +347,25 @@ class GraphQlAutoConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
static class CustomTypeDefinitionConfigurer {
@Bean
TestTypeDefinitionConfigurer testTypeDefinitionConfigurer() {
return new TestTypeDefinitionConfigurer();
}
}
static class TestTypeDefinitionConfigurer implements TypeDefinitionConfigurer {
boolean applied = false;
@Override
public void configure(TypeDefinitionRegistry registry) {
this.applied = true;
}
}
}