Last active
October 13, 2022 09:51
-
-
Save maciejwalkowiak/3d1f251da7f18dc090cad53518da8409 to your computer and use it in GitHub Desktop.
Support for GET requests in Spring for GraphQL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Objects; | |
import org.springframework.boot.autoconfigure.graphql.GraphQlProperties; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.context.annotation.Configuration; | |
import org.springframework.core.annotation.Order; | |
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.ServerResponse; | |
@Configuration | |
public class GraphQlConfiguration { | |
@Bean | |
@Order(-1) | |
public RouterFunction<ServerResponse> graphQlGetRouterFunction(GetRequestGraphQlHttpHandler gethttpHandler, | |
GraphQlProperties properties) { | |
return RouterFunctions | |
.route() | |
.GET(properties.getPath(), RequestPredicates.param("query", Objects::nonNull), gethttpHandler::handleRequest) | |
.build(); | |
} | |
} |
How do you secure that endpoint via CORS? Usually you have to incorporate mapping. In this case you are changing the mapping used to what appears to be SimpleUrlMapping
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
With httpie:
This is a naive implementation so use with caution:
Read more: