From 65ef8994001e178913d7ee5e297959e58e75d764 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Mon, 11 Mar 2024 11:03:39 +0100 Subject: [PATCH] Use optimized request predicates for GraphQL endpoints Prior to this commit, Spring Boot auto-configurations for GraphQL web endpoint were implementing their own `RequestPredicate` instances for HTTP endpoints. Those were composing predicates with the provided DSL. While this is functionnally right, Spring for GraphQL now provides predicates in order to: * host the implementation in spring-graphql directly * provide optimized predicates for faster matching and lower overhead This commit switches the auto-configurations to using these new predicates. Closes gh-39652 --- .../reactive/GraphQlWebFluxAutoConfiguration.java | 13 ++----------- .../servlet/GraphQlWebMvcAutoConfiguration.java | 9 ++------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/reactive/GraphQlWebFluxAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/reactive/GraphQlWebFluxAutoConfiguration.java index 12d0dd3d18..50fbfa6a7f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/reactive/GraphQlWebFluxAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/reactive/GraphQlWebFluxAutoConfiguration.java @@ -47,19 +47,18 @@ import org.springframework.graphql.execution.GraphQlSource; import org.springframework.graphql.server.WebGraphQlHandler; import org.springframework.graphql.server.WebGraphQlInterceptor; import org.springframework.graphql.server.webflux.GraphQlHttpHandler; +import org.springframework.graphql.server.webflux.GraphQlRequestPredicates; import org.springframework.graphql.server.webflux.GraphQlWebSocketHandler; import org.springframework.graphql.server.webflux.GraphiQlHandler; import org.springframework.graphql.server.webflux.SchemaHandler; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.codec.ServerCodecConfigurer; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.reactive.HandlerMapping; import org.springframework.web.reactive.config.CorsRegistry; import org.springframework.web.reactive.config.WebFluxConfigurer; -import org.springframework.web.reactive.function.server.RequestPredicate; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerRequest; @@ -67,9 +66,6 @@ import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping; import org.springframework.web.reactive.socket.server.support.WebSocketUpgradeHandlerPredicate; -import static org.springframework.web.reactive.function.server.RequestPredicates.accept; -import static org.springframework.web.reactive.function.server.RequestPredicates.contentType; - /** * {@link EnableAutoConfiguration Auto-configuration} for enabling Spring GraphQL over * WebFlux. @@ -85,11 +81,6 @@ import static org.springframework.web.reactive.function.server.RequestPredicates @ImportRuntimeHints(GraphQlWebFluxAutoConfiguration.GraphiQlResourceHints.class) public class GraphQlWebFluxAutoConfiguration { - @SuppressWarnings("removal") - private static final RequestPredicate SUPPORTS_MEDIATYPES = accept(MediaType.APPLICATION_GRAPHQL_RESPONSE, - MediaType.APPLICATION_JSON, MediaType.APPLICATION_GRAPHQL) - .and(contentType(MediaType.APPLICATION_JSON)); - private static final Log logger = LogFactory.getLog(GraphQlWebFluxAutoConfiguration.class); @Bean @@ -112,7 +103,7 @@ public class GraphQlWebFluxAutoConfiguration { String path = properties.getPath(); logger.info(LogMessage.format("GraphQL endpoint HTTP POST %s", path)); RouterFunctions.Builder builder = RouterFunctions.route(); - builder = builder.POST(path, SUPPORTS_MEDIATYPES, httpHandler::handleRequest); + builder.route(GraphQlRequestPredicates.graphQlHttp(path), httpHandler::handleRequest); builder = builder.GET(path, this::onlyAllowPost); if (properties.getGraphiql().isEnabled()) { GraphiQlHandler graphQlHandler = new GraphiQlHandler(path, properties.getWebsocket().getPath()); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/servlet/GraphQlWebMvcAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/servlet/GraphQlWebMvcAutoConfiguration.java index e9ecabc0c1..074f32452f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/servlet/GraphQlWebMvcAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/servlet/GraphQlWebMvcAutoConfiguration.java @@ -49,6 +49,7 @@ import org.springframework.graphql.execution.GraphQlSource; import org.springframework.graphql.server.WebGraphQlHandler; import org.springframework.graphql.server.WebGraphQlInterceptor; import org.springframework.graphql.server.webmvc.GraphQlHttpHandler; +import org.springframework.graphql.server.webmvc.GraphQlRequestPredicates; import org.springframework.graphql.server.webmvc.GraphQlWebSocketHandler; import org.springframework.graphql.server.webmvc.GraphiQlHandler; import org.springframework.graphql.server.webmvc.SchemaHandler; @@ -62,7 +63,6 @@ import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.springframework.web.servlet.function.RequestPredicates; import org.springframework.web.servlet.function.RouterFunction; import org.springframework.web.servlet.function.RouterFunctions; import org.springframework.web.servlet.function.ServerRequest; @@ -88,10 +88,6 @@ public class GraphQlWebMvcAutoConfiguration { private static final Log logger = LogFactory.getLog(GraphQlWebMvcAutoConfiguration.class); - @SuppressWarnings("removal") - private static final MediaType[] SUPPORTED_MEDIA_TYPES = new MediaType[] { MediaType.APPLICATION_GRAPHQL_RESPONSE, - MediaType.APPLICATION_JSON, MediaType.APPLICATION_GRAPHQL }; - @Bean @ConditionalOnMissingBean public GraphQlHttpHandler graphQlHttpHandler(WebGraphQlHandler webGraphQlHandler) { @@ -112,8 +108,7 @@ public class GraphQlWebMvcAutoConfiguration { String path = properties.getPath(); logger.info(LogMessage.format("GraphQL endpoint HTTP POST %s", path)); RouterFunctions.Builder builder = RouterFunctions.route(); - builder = builder.POST(path, RequestPredicates.contentType(MediaType.APPLICATION_JSON) - .and(RequestPredicates.accept(SUPPORTED_MEDIA_TYPES)), httpHandler::handleRequest); + builder.route(GraphQlRequestPredicates.graphQlHttp(path), httpHandler::handleRequest); builder = builder.GET(path, this::onlyAllowPost); if (properties.getGraphiql().isEnabled()) { GraphiQlHandler graphiQLHandler = new GraphiQlHandler(path, properties.getWebsocket().getPath());