From f711dad1b60fe34558594f87737b19c5b7c091f3 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Fri, 13 Nov 2020 11:52:13 +0100 Subject: [PATCH] Introduce GraphiQL integration This commit adds a very simple graphiQL integration: we're shipping the project with a sample graphiQL `index.html` page that's relying on CDNs to display the explorer. We're also plugging in that resource at the graphQL endpoint location, responding to GET requests. This is not a problem since for now we're only considering POST requests to the endpoint for actual queries. Closes gh-12 --- .../WebFluxGraphQLAutoConfiguration.java | 10 +- .../WebMvcGraphQLAutoConfiguration.java | 10 +- .../META-INF/spring-devtools.properties | 1 + .../src/main/resources/graphiql/index.html | 92 +++++++++++++++++++ 4 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 spring-graphql-web/src/main/resources/META-INF/spring-devtools.properties create mode 100644 spring-graphql-web/src/main/resources/graphiql/index.html diff --git a/spring-graphql-web/src/main/java/org/springframework/boot/graphql/WebFluxGraphQLAutoConfiguration.java b/spring-graphql-web/src/main/java/org/springframework/boot/graphql/WebFluxGraphQLAutoConfiguration.java index 63187d5b..2e68cf10 100644 --- a/spring-graphql-web/src/main/java/org/springframework/boot/graphql/WebFluxGraphQLAutoConfiguration.java +++ b/spring-graphql-web/src/main/java/org/springframework/boot/graphql/WebFluxGraphQLAutoConfiguration.java @@ -26,6 +26,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ResourceLoader; import org.springframework.graphql.WebFluxGraphQLHandler; import org.springframework.http.MediaType; import org.springframework.web.reactive.function.server.RouterFunction; @@ -33,6 +34,7 @@ import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerResponse; import static org.springframework.web.reactive.function.server.RequestPredicates.accept; +import static org.springframework.web.reactive.function.server.RequestPredicates.contentType; @Configuration @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) @@ -48,8 +50,12 @@ public class WebFluxGraphQLAutoConfiguration { } @Bean - public RouterFunction graphQLQueryEndpoint(WebFluxGraphQLHandler handler, GraphQLProperties graphQLProperties) { - return RouterFunctions.route().POST(graphQLProperties.getPath(), accept(MediaType.APPLICATION_JSON), handler).build(); + public RouterFunction graphQLQueryEndpoint(ResourceLoader resourceLoader, WebFluxGraphQLHandler handler, + GraphQLProperties graphQLProperties) { + return RouterFunctions.route() + .GET(graphQLProperties.getPath(), req -> ServerResponse.ok().bodyValue(resourceLoader.getResource("classpath:graphiql/index.html"))) + .POST(graphQLProperties.getPath(), accept(MediaType.APPLICATION_JSON).and(contentType(MediaType.APPLICATION_JSON)), handler) + .build(); } } diff --git a/spring-graphql-web/src/main/java/org/springframework/boot/graphql/WebMvcGraphQLAutoConfiguration.java b/spring-graphql-web/src/main/java/org/springframework/boot/graphql/WebMvcGraphQLAutoConfiguration.java index ea498b8c..0a8ec093 100644 --- a/spring-graphql-web/src/main/java/org/springframework/boot/graphql/WebMvcGraphQLAutoConfiguration.java +++ b/spring-graphql-web/src/main/java/org/springframework/boot/graphql/WebMvcGraphQLAutoConfiguration.java @@ -26,6 +26,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ResourceLoader; import org.springframework.graphql.WebMvcGraphQLHandler; import org.springframework.http.MediaType; import org.springframework.web.servlet.function.RouterFunction; @@ -33,9 +34,10 @@ import org.springframework.web.servlet.function.RouterFunctions; import org.springframework.web.servlet.function.ServerResponse; import static org.springframework.web.servlet.function.RequestPredicates.accept; +import static org.springframework.web.servlet.function.RequestPredicates.contentType; @Configuration -@ConditionalOnWebApplication +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) @ConditionalOnClass(GraphQL.class) @ConditionalOnBean(GraphQL.Builder.class) @AutoConfigureAfter(GraphQLAutoConfiguration.class) @@ -48,9 +50,11 @@ public class WebMvcGraphQLAutoConfiguration { } @Bean - public RouterFunction graphQLQueryEndpoint(WebMvcGraphQLHandler handler, GraphQLProperties graphQLProperties) { + public RouterFunction graphQLQueryEndpoint(ResourceLoader resourceLoader, WebMvcGraphQLHandler handler, + GraphQLProperties graphQLProperties) { return RouterFunctions.route() - .POST(graphQLProperties.getPath(), accept(MediaType.APPLICATION_JSON), handler) + .GET(graphQLProperties.getPath(), req -> ServerResponse.ok().body(resourceLoader.getResource("classpath:graphiql/index.html"))) + .POST(graphQLProperties.getPath(), contentType(MediaType.APPLICATION_JSON).and(accept(MediaType.APPLICATION_JSON)), handler) .build(); } diff --git a/spring-graphql-web/src/main/resources/META-INF/spring-devtools.properties b/spring-graphql-web/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 00000000..cf65371f --- /dev/null +++ b/spring-graphql-web/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.graphql-java=graphql-java.*\.jar \ No newline at end of file diff --git a/spring-graphql-web/src/main/resources/graphiql/index.html b/spring-graphql-web/src/main/resources/graphiql/index.html new file mode 100644 index 00000000..cc0d57d7 --- /dev/null +++ b/spring-graphql-web/src/main/resources/graphiql/index.html @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + +
Loading...
+ + + + +