This projects builds on Boot 2.5.x, but it should be compatible with the latest Boot 2.4.x.
Project Setup
To create a project, go to https://start.spring.io and select starter(s) for the GraphQL transports you want to use:
| Starter | Transport | Implementation |
|---|---|---|
|
HTTP |
Spring MVC |
|
WebSocket |
WebSocket for Servlet apps |
|
HTTP, WebSocket |
Spring WebFlux |
In the generated project, add graphql-spring-boot-starter manually:
dependencies {
// Spring GraphQL Boot starter
implementation 'org.springframework.experimental:graphql-spring-boot-starter:1.0.0-SNAPSHOT'
// ...
}
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' } // Spring milestones
maven { url 'https://repo.spring.io/snapshot' } // Spring snapshots
}
<dependencies>
// Spring GraphQL Boot starter
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<!-- ... -->
</dependencies>
<!-- For Spring project milestones or snapshot releases -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
|
Boot Starter Group Id
The Boot starter will move from the Spring GraphQL repository to the Spring Boot
repository, after Spring Boot 2.6 is released. The group id for the starter will then
change from |
Schema
By default, GraphQL schema files are expected to be in src/main/resources/graphql and have
the extension ".graphqls", ".graphql", ".gql", or ".gqls". You can customize the
schema locations to check as follows:
spring.graphql.schema.locations=classpath:graphql/
The GraphQL schema can be viewed over HTTP at "/graphql/schema". This is not enabled by default:
spring.graphql.schema.printer.enabled=false
RuntimeWiring
The GraphQL Java RuntimeWiring.Builder can be used to register DataFetchers,
type resolvers, custom scalar types, and more. You can declare RuntimeWiringConfigurer
beans in your Spring config to get access to the RuntimeWiring.Builder. The Boot
starter detects such beans adds them to GraphQlSource.Builder.
Typically, however, applications will not implement DataFetcher directly and will
instead create annotated controllers. The Boot
starter declares a RuntimeWiringConfigurer called AnnotatedDataFetcherConfigurer that
detects @Controller classes with annotated handler methods and registers those as
DataFetchers.
Querydsl Repositories
Spring Data repositories that extend QuerydslPredicateExecutor or
ReactiveQuerydslPredicateExecutor and are annotated with @GraphQlRepository are
detected and considered as candidates for DataFetcher
auto registration for matching top-level queries.
Web Endpoints
The GraphQL HTTP endpoint is at HTTP POST "/graphql" by default. The path can be customized:
spring.graphql.path=/graphql
The GraphQL WebSocket endpoint supports WebSocket handshakes at "/graphql" by default. The below shows the properties that apply for WebSocket handling:
spring.graphql.websocket.path=/graphql
# Time within which a "CONNECTION_INIT" message must be received from the client
spring.graphql.websocket.connection-init-timeout=60s
The GraphQL WebSocket endpoint is off by default. To enable it:
-
For a Servlet application, add the WebSocket starter
spring-boot-starter-websocket. -
For a WebFlux application, set the
spring.graphql.websocket.pathapplication property.
Declare a WebInterceptor bean to have it registered in the
Web Interception for GraphQL over HTTP and WebSocket
requests.
Declare a ThreadLocalAccessor bean to assist with the propagation of ThreadLocal
values of interest in Spring MVC.
GraphiQL
The Spring Boot starter includes a GraphiQL page that is exposed at "/graphiql" by default. You can configure this as follows:
spring.graphql.graphiql.enabled=true
spring.graphql.graphiql.path=/graphiql
Metrics
When the starter spring-boot-starter-actuator is present on the classpath, metrics for
GraphQL requests are collected. You can disable metrics collection as follows:
management.metrics.graphql.autotime.enabled=false
Metrics can be exposed with an Actuator web endpoint. The following sections assume that its exposure is enabled in your application configuration, as follows:
management.endpoints.web.exposure.include=health,metrics,info
Request Timer
A Request metric timer is available at /actuator/metrics/graphql.request.
| Tag | Description | Sample values |
|---|---|---|
outcome |
Request outcome |
"SUCCESS", "ERROR" |
Testing
For Spring GraphQL testing support, add the below to your classpath and that will make
a WebGraphQlTester available for injection into tests:
dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.graphql:spring-graphql-test:1.0.0-SNAPSHOT'
// Also add this, unless spring-boot-starter-webflux is also present
testImplementation 'org.springframework:spring-webflux'
// ...
}
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' } // Spring milestones
maven { url 'https://repo.spring.io/snapshot' } // Spring snapshots
}
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.graphql</groupId>
<artifactId>spring-graphql-test</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<!-- Also add this, unless "spring-boot-starter-webflux" is also present -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<scope>test</scope>
</dependency>
<!-- ... -->
</dependencies>
<!-- For Spring project milestones or snapshot releases -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
For GraphQL over HTTP with Spring MVC, using MockMvc as the server:
@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureGraphQlTester
public class MockMvcGraphQlTests {
@Autowired
private WebGraphQlTester graphQlTester;
}
For GraphQL over HTTP with Spring WebFlux, using a mock server:
@SpringBootTest
@AutoConfigureWebTestClient
@AutoConfigureGraphQlTester
public class MockMvcGraphQlTests {
@Autowired
private WebGraphQlTester graphQlTester;
}
For GraphQL over HTTP with a running server:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureGraphQlTester
public class MockMvcGraphQlTests {
@Autowired
private WebGraphQlTester graphQlTester;
}
Subscriptions can be tested without WebSocket as shown below:
@SpringBootTest
@AutoConfigureGraphQlTester
public class MockMvcGraphQlTests {
@Autowired
private WebGraphQlTester graphQlTester;
@Test
void subscription() {
Flux<String> result = this.graphQlTester.query("subscription { greetings }")
.executeSubscription()
.toFlux("greetings", String.class);
// Use StepVerifier from "reactor-test" to verify the stream...
StepVerifier.create(result)
.expectNext("Hi")
.expectNext("Bonjour")
.expectNext("Hola")
.verifyComplete();
}
}
The above subscription test is performed directly against the WebGraphQlHandler that
both HTTP and WebSocket transports delegate to. It passes through the WebInterceptor
chain and then calls GraphQL Java which returns a Reactive Streams Publisher.