From 054aaedb16a258f0bd84ff6594e27853752b537b Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Mon, 15 May 2023 10:46:12 +0200 Subject: [PATCH] Document GraphiQL integration Closes gh-403 --- .../src/docs/asciidoc/includes/graphiql.adoc | 38 ++++++++++++++++++ .../src/docs/asciidoc/index.adoc | 4 ++ .../configuration/GraphiQlConfiguration.java | 40 +++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 spring-graphql-docs/src/docs/asciidoc/includes/graphiql.adoc create mode 100644 spring-graphql-docs/src/main/java/org/springframework/graphql/docs/graphiql/configuration/GraphiQlConfiguration.java diff --git a/spring-graphql-docs/src/docs/asciidoc/includes/graphiql.adoc b/spring-graphql-docs/src/docs/asciidoc/includes/graphiql.adoc new file mode 100644 index 00000000..c77f39d0 --- /dev/null +++ b/spring-graphql-docs/src/docs/asciidoc/includes/graphiql.adoc @@ -0,0 +1,38 @@ +[[graphiql]] += GraphiQL + +https://github.com/graphql/graphiql/tree/main/packages/graphiql#readme[GraphiQL] is a graphical interactive in-browser GraphQL IDE. +It is very popular amongst developers as it makes it easy to explore and interactively develop GraphQL APIs. +During development, a stock GraphiQL integration is often enough to help developers work on an API. +In production, applications can require a custom GraphiQL build, that ships with a company logo or specific authentication support. + +Spring for GraphQL ships with https://github.com/spring-projects/spring-graphql/blob/main/spring-graphql/src/main/resources/graphiql/index.html[a stock GraphiQL `index.html` page] that uses static resources hosted on the unpkg.com CDN. +Spring Boot applications can easily {spring-boot-ref-docs}/web.html#web.graphql.graphiql[enable this page with a configuration property]. + +Your application may need a custom GraphiQL build if it requires a setup that doesn't rely on a CDN, or if you wish to customize the user interface. +This can be done in two steps: + +1. Configure and compile a GraphiQL build +2. Expose the built GraphiQL instance through the Spring web infrastructure + +[[graphiql.custombuild]] +== Creating a custom GraphiQL build + +This part is generally outside of the scope of this documentation, as there are several options for custom builds. +You will find more information in the https://github.com/graphql/graphiql/tree/main/packages/graphiql#readme[official GraphiQL documentation]. +You can choose to copy the build result directly in your application resources. +Alternatively, you can integrate the JavaScript build in your project as a separate module by leveraging Node.js https://github.com/node-gradle/gradle-node-plugin[Gradle] or https://github.com/eirslett/frontend-maven-plugin[Maven] build plugins. + + +[[graphiql.configuration]] +== Exposing a GraphiQL instance + +Once a GraphiQL build is available on the classpath, you can expose it as an endpoint with the {spring-framework-ref-docs}/web/webmvc-functional.html#webmvc-fn-router-functions[functional web frameworks]. + +include::code:GraphiQlConfiguration[] +<1> Load the GraphiQL page from the classpath (here, we are using the version shipped with Spring for GraphQL) +<2> Configure a web handler for processing HTTP requests; you can implement a custom `HandlerFunction` depending on your use case +<3> Finally, map the handler to a specific HTTP endpoint +<4> Expose this new route through a `RouterFunction` bean + +You might also need to configure your application to {spring-boot-ref-docs}/web.html#web.servlet.spring-mvc.static-content[serve the relevant static resources]. \ No newline at end of file diff --git a/spring-graphql-docs/src/docs/asciidoc/index.adoc b/spring-graphql-docs/src/docs/asciidoc/index.adoc index e259e1ec..3d0a9a50 100644 --- a/spring-graphql-docs/src/docs/asciidoc/index.adoc +++ b/spring-graphql-docs/src/docs/asciidoc/index.adoc @@ -71,6 +71,10 @@ include::includes/client.adoc[leveloffset=+1] +include::includes/graphiql.adoc[leveloffset=+1] + + + include::includes/testing.adoc[leveloffset=+1] diff --git a/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/graphiql/configuration/GraphiQlConfiguration.java b/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/graphiql/configuration/GraphiQlConfiguration.java new file mode 100644 index 00000000..3ffb4e17 --- /dev/null +++ b/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/graphiql/configuration/GraphiQlConfiguration.java @@ -0,0 +1,40 @@ +/* + * Copyright 2020-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.graphql.docs.graphiql.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.core.io.ClassPathResource; +import org.springframework.graphql.server.webmvc.GraphiQlHandler; +import org.springframework.web.servlet.function.RouterFunction; +import org.springframework.web.servlet.function.RouterFunctions; +import org.springframework.web.servlet.function.ServerResponse; + +@Configuration +public class GraphiQlConfiguration { + + @Bean + @Order(0) + public RouterFunction graphiQlRouterFunction() { + RouterFunctions.Builder builder = RouterFunctions.route(); + ClassPathResource graphiQlPage = new ClassPathResource("graphiql/index.html"); // <1> + GraphiQlHandler graphiQLHandler = new GraphiQlHandler("/graphql", "", graphiQlPage); // <2> + builder = builder.GET("/graphiql", graphiQLHandler::handleRequest); // <3> + return builder.build(); // <4> + } +}