Allow configuring custom GraphQL argument resolvers

This commit gathers `HandlerMethodArgumentResolver` beans contributed by
the application and sets them up on the auto-configured
`AnnotatedControllerConfigurer` bean.

This allows easier registrationsfor custom argument resolvers in Spring
for GraphQL applications.

Closes gh-40393
This commit is contained in:
maxhov 2024-07-20 15:10:59 +02:00 committed by Brian Clozel
parent 3ef2bcfe82
commit 3561ab8300
2 changed files with 23 additions and 1 deletions

View File

@ -49,6 +49,7 @@ import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.log.LogMessage;
import org.springframework.data.domain.ScrollPosition;
import org.springframework.graphql.ExecutionGraphQlService;
import org.springframework.graphql.data.method.HandlerMethodArgumentResolver;
import org.springframework.graphql.data.method.annotation.support.AnnotatedControllerConfigurer;
import org.springframework.graphql.data.pagination.ConnectionFieldTypeVisitor;
import org.springframework.graphql.data.pagination.CursorEncoder;
@ -154,11 +155,13 @@ public class GraphQlAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public AnnotatedControllerConfigurer annotatedControllerConfigurer(
@Qualifier(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME) ObjectProvider<Executor> executorProvider) {
@Qualifier(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME) ObjectProvider<Executor> executorProvider,
ObjectProvider<HandlerMethodArgumentResolver> argumentResolvers) {
AnnotatedControllerConfigurer controllerConfigurer = new AnnotatedControllerConfigurer();
controllerConfigurer
.addFormatterRegistrar((registry) -> ApplicationConversionService.addBeans(registry, this.beanFactory));
executorProvider.ifAvailable(controllerConfigurer::setExecutor);
argumentResolvers.orderedStream().forEach(controllerConfigurer::addCustomArgumentResolver);
return controllerConfigurer;
}

View File

@ -45,6 +45,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.graphql.ExecutionGraphQlService;
import org.springframework.graphql.data.method.HandlerMethodArgumentResolver;
import org.springframework.graphql.data.method.annotation.support.AnnotatedControllerConfigurer;
import org.springframework.graphql.data.pagination.EncodingCursorStrategy;
import org.springframework.graphql.execution.BatchLoaderRegistry;
@ -241,6 +242,15 @@ class GraphQlAutoConfigurationTests {
});
}
@Test
void whenAHandlerMethodArgumentResolverIsDefinedThenAnnotatedControllerConfigurerShouldUseIt() {
this.contextRunner.withUserConfiguration(CustomHandlerMethodArgumentResolverConfiguration.class)
.run((context) -> assertThat(context.getBean(AnnotatedControllerConfigurer.class))
.extracting("customArgumentResolvers")
.asInstanceOf(InstanceOfAssertFactories.LIST)
.hasSize(1));
}
@Configuration(proxyBeanMethods = false)
static class CustomGraphQlBuilderConfiguration {
@ -336,4 +346,13 @@ class GraphQlAutoConfigurationTests {
}
static class CustomHandlerMethodArgumentResolverConfiguration {
@Bean
HandlerMethodArgumentResolver customHandlerMethodArgumentResolver() {
return mock(HandlerMethodArgumentResolver.class);
}
}
}