Document minimum standalone setup for GraphQL support

Most Spring for GraphQL applications use Spring Boot as a way to
auto-configure the required infrastructure for running GraphQL
applications.

This commit documents a minimal setup for Spring applications not
relying on Spring Boot. This assumes an existing infrastructure for a
Spring MVC application.

Closes gh-606
This commit is contained in:
Brian Clozel
2024-07-12 16:06:48 +02:00
parent 441b18d919
commit c1ed773cc7
3 changed files with 89 additions and 0 deletions

View File

@@ -12,4 +12,5 @@
* xref:graphiql.adoc[]
* xref:testing.adoc[]
* xref:boot-starter.adoc[]
* xref:standalone-setup.adoc[]
* xref:samples.adoc[]

View File

@@ -0,0 +1,15 @@
[[standalone-setup]]
= Standalone Setup
If your application is not using Spring Boot, you are responsible for setting up the relevant Spring for GraphQL components.
Assuming that your application is already configured for Spring MVC controllers, the minimum setup will require several beans.
include-code::GraphQlConfiguration[]
<1> The `AnnotatedControllerConfigurer` bean is responsible for detecting GraphQL `@Controller` handlers.
<2> The `ExecutionGraphQlService` processes GraphQL requests in a transport-agnostic fashion.
<3> The `GraphQlSource` builder is the main configuration point. Explore its API for more options.
<4> The `RouterFunction` exposes the GraphQL routes as {spring-framework-ref-docs}/web/webmvc-functional.html[functional endpoints].
<5> You can then expose various transports (WebSocket, SSE, HTTP) over different routes.
Spring for GraphQL offers many other options and integrations with Spring projects.
For more on this, you can xref:boot-starter.adoc[explore the Spring Boot auto-configurations].

View File

@@ -0,0 +1,73 @@
/*
* Copyright 2020-2024 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.standalonesetup;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.graphql.ExecutionGraphQlService;
import org.springframework.graphql.data.method.annotation.support.AnnotatedControllerConfigurer;
import org.springframework.graphql.execution.ConnectionTypeDefinitionConfigurer;
import org.springframework.graphql.execution.DefaultBatchLoaderRegistry;
import org.springframework.graphql.execution.DefaultExecutionGraphQlService;
import org.springframework.graphql.execution.GraphQlSource;
import org.springframework.graphql.server.WebGraphQlHandler;
import org.springframework.graphql.server.webmvc.GraphQlHttpHandler;
import org.springframework.graphql.server.webmvc.GraphQlRequestPredicates;
import org.springframework.graphql.server.webmvc.GraphiQlHandler;
import org.springframework.web.servlet.function.RequestPredicate;
import org.springframework.web.servlet.function.RouterFunction;
import org.springframework.web.servlet.function.RouterFunctions;
import org.springframework.web.servlet.function.ServerResponse;
@Configuration(proxyBeanMethods = false)
public class GraphQlConfiguration {
@Bean // <1>
public AnnotatedControllerConfigurer controllerConfigurer() {
return new AnnotatedControllerConfigurer();
}
@Bean // <2>
public ExecutionGraphQlService executionGraphQlService(AnnotatedControllerConfigurer controllerConfigurer) {
GraphQlSource graphQlSource = GraphQlSource.schemaResourceBuilder() // <3>
.schemaResources(new ClassPathResource("graphql/schema.graphqls"))
.configureTypeDefinitions(new ConnectionTypeDefinitionConfigurer())
.configureRuntimeWiring(controllerConfigurer)
.exceptionResolvers(List.of(controllerConfigurer.getExceptionResolver()))
.build();
DefaultBatchLoaderRegistry batchLoaderRegistry = new DefaultBatchLoaderRegistry();
DefaultExecutionGraphQlService service = new DefaultExecutionGraphQlService(graphQlSource);
service.addDataLoaderRegistrar(batchLoaderRegistry);
return service;
}
@Bean // <4>
public RouterFunction<ServerResponse> graphQlRouterFunction(ExecutionGraphQlService graphQlService) {
WebGraphQlHandler webGraphQlHandler = WebGraphQlHandler.builder(graphQlService).build();
GraphQlHttpHandler graphQlHttpHandler = new GraphQlHttpHandler(webGraphQlHandler);
RequestPredicate graphQlPredicate = GraphQlRequestPredicates.graphQlHttp("/graphql");
GraphiQlHandler graphiQlHandler = new GraphiQlHandler("/graphql", "");
return RouterFunctions.route() // <5>
.route(graphQlPredicate, graphQlHttpHandler::handleRequest)
.GET("/graphiql", graphiQlHandler::handleRequest)
.build();
}
}