import java.util.Arrays; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import reactor.core.publisher.Mono; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.graphql.server.WebGraphQlHandler; import org.springframework.graphql.server.WebGraphQlRequest; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import org.springframework.util.AlternativeJdkIdGenerator; import org.springframework.util.IdGenerator; import org.springframework.web.servlet.function.ServerRequest; import org.springframework.web.servlet.function.ServerResponse; @Component public class GetRequestGraphQlHttpHandler { private static final Log logger = LogFactory.getLog(GetRequestGraphQlHttpHandler.class); private static final List<MediaType> SUPPORTED_MEDIA_TYPES = Arrays.asList(MediaType.APPLICATION_GRAPHQL, MediaType.APPLICATION_JSON); private final IdGenerator idGenerator = new AlternativeJdkIdGenerator(); private final WebGraphQlHandler graphQlHandler; GetRequestGraphQlHttpHandler(WebGraphQlHandler graphQlHandler) { this.graphQlHandler = graphQlHandler; } public ServerResponse handleRequest(ServerRequest serverRequest) { String query = serverRequest.param("query").orElseThrow(() -> new RuntimeException("'query' parameter not set")); WebGraphQlRequest graphQlRequest = new WebGraphQlRequest( serverRequest.uri(), serverRequest.headers().asHttpHeaders(), Map.of("query", query), this.idGenerator.generateId().toString(), LocaleContextHolder.getLocale()); if (logger.isDebugEnabled()) { logger.debug("Executing: " + graphQlRequest); } Mono<ServerResponse> responseMono = this.graphQlHandler.handleRequest(graphQlRequest) .map(response -> { if (logger.isDebugEnabled()) { logger.debug("Execution complete"); } ServerResponse.BodyBuilder builder = ServerResponse.ok(); builder.headers(headers -> headers.putAll(response.getResponseHeaders())); builder.contentType(selectResponseMediaType(serverRequest)); return builder.body(response.toMap()); }); return ServerResponse.async(responseMono); } private static MediaType selectResponseMediaType(ServerRequest serverRequest) { for (MediaType accepted : serverRequest.headers().accept()) { if (SUPPORTED_MEDIA_TYPES.contains(accepted)) { return accepted; } } return MediaType.APPLICATION_JSON; } }