From 3561ab83001f49652568561f537b5b2c41a7e736 Mon Sep 17 00:00:00 2001 From: maxhov <14804474+maxhov@users.noreply.github.com> Date: Sat, 20 Jul 2024 15:10:59 +0200 Subject: [PATCH] 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 --- .../graphql/GraphQlAutoConfiguration.java | 5 ++++- .../GraphQlAutoConfigurationTests.java | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfiguration.java index 9b9c408d7a58..599b613ad4a5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfiguration.java @@ -49,6 +49,7 @@ 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 ExecutionGraphQlService executionGraphQlService(GraphQlSource graphQlSour @Bean @ConditionalOnMissingBean public AnnotatedControllerConfigurer annotatedControllerConfigurer( - @Qualifier(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME) ObjectProvider executorProvider) { + @Qualifier(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME) ObjectProvider executorProvider, + ObjectProvider argumentResolvers) { AnnotatedControllerConfigurer controllerConfigurer = new AnnotatedControllerConfigurer(); controllerConfigurer .addFormatterRegistrar((registry) -> ApplicationConversionService.addBeans(registry, this.beanFactory)); executorProvider.ifAvailable(controllerConfigurer::setExecutor); + argumentResolvers.orderedStream().forEach(controllerConfigurer::addCustomArgumentResolver); return controllerConfigurer; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfigurationTests.java index 75a44a5ce596..62aab64c17a9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfigurationTests.java @@ -45,6 +45,7 @@ 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 @@ void whenCustomExecutorIsDefinedThenAnnotatedControllerConfigurerDoesNotUseIt() }); } + @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 @@ Executor customExecutor() { } + static class CustomHandlerMethodArgumentResolverConfiguration { + + @Bean + HandlerMethodArgumentResolver customHandlerMethodArgumentResolver() { + return mock(HandlerMethodArgumentResolver.class); + } + + } + }