|
|
|
|
@@ -1,582 +0,0 @@
|
|
|
|
|
[[boot-graphql]]
|
|
|
|
|
= Boot Starter
|
|
|
|
|
|
|
|
|
|
This projects builds on Boot 2.6.x, but it should be compatible with the latest Boot 2.4.x.
|
|
|
|
|
For QueryDSL-related features, Spring Data 2021.1.0 or later is required.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-project]]
|
|
|
|
|
== Project Setup
|
|
|
|
|
|
|
|
|
|
To create a project, go to https://start.spring.io and select starter(s) for the
|
|
|
|
|
GraphQL transports you want to use:
|
|
|
|
|
|
|
|
|
|
[cols="1,1,1"]
|
|
|
|
|
|===
|
|
|
|
|
| Starter | Transport | Implementation
|
|
|
|
|
|
|
|
|
|
| `spring-boot-starter-web`
|
|
|
|
|
| HTTP
|
|
|
|
|
| Spring MVC
|
|
|
|
|
|
|
|
|
|
| `spring-boot-starter-websocket`
|
|
|
|
|
| WebSocket
|
|
|
|
|
| WebSocket for Servlet apps
|
|
|
|
|
|
|
|
|
|
| `spring-boot-starter-webflux`
|
|
|
|
|
| HTTP, WebSocket
|
|
|
|
|
| Spring WebFlux
|
|
|
|
|
|
|
|
|
|
|===
|
|
|
|
|
|
|
|
|
|
In the generated project, add `graphql-spring-boot-starter` manually:
|
|
|
|
|
|
|
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes",role="primary"]
|
|
|
|
|
.Gradle
|
|
|
|
|
----
|
|
|
|
|
dependencies {
|
|
|
|
|
// Spring GraphQL Boot starter
|
|
|
|
|
implementation 'org.springframework.experimental:graphql-spring-boot-starter:{spring-graphql-version}'
|
|
|
|
|
|
|
|
|
|
// ...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
repositories {
|
|
|
|
|
mavenCentral()
|
|
|
|
|
maven { url 'https://repo.spring.io/milestone' } // Spring milestones
|
|
|
|
|
maven { url 'https://repo.spring.io/snapshot' } // Spring snapshots
|
|
|
|
|
}
|
|
|
|
|
----
|
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes",role="secondary"]
|
|
|
|
|
.Maven
|
|
|
|
|
----
|
|
|
|
|
<dependencies>
|
|
|
|
|
|
|
|
|
|
<!-- Spring GraphQL Boot starter -->
|
|
|
|
|
<dependency>
|
|
|
|
|
<groupId>org.springframework.experimental</groupId>
|
|
|
|
|
<artifactId>graphql-spring-boot-starter</artifactId>
|
|
|
|
|
<version>{spring-graphql-version}</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>
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
[NOTE]
|
|
|
|
|
.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 `org.springframework.experimental` to `org.springframework.boot` and will be
|
|
|
|
|
released in Spring Boot 2.7.
|
|
|
|
|
====
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-schema]]
|
|
|
|
|
== Schema
|
|
|
|
|
|
|
|
|
|
By default, the Boot starter checks in `src/main/resources/graphql` for GraphQL schema
|
|
|
|
|
files with extensions ".graphqls" or ".gqls". To customize this, use the following:
|
|
|
|
|
|
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes"]
|
|
|
|
|
----
|
|
|
|
|
spring.graphql.schema.locations=classpath:graphql/
|
|
|
|
|
spring.graphql.schema.fileExtensions=.graphqls, .gqls
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
The GraphQL schema can be viewed at HTTP GET /graphql/schema. This is off by default and
|
|
|
|
|
needs to be enabled:
|
|
|
|
|
|
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes"]
|
|
|
|
|
----
|
|
|
|
|
spring.graphql.schema.printer.enabled=false
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-runtimewiring]]
|
|
|
|
|
== RuntimeWiring
|
|
|
|
|
|
|
|
|
|
The GraphQL Java `RuntimeWiring.Builder` can be used to register custom scalar types,
|
|
|
|
|
directives, type resolvers, ``DataFetcher``s, and more. You can declare `RuntimeWiringConfigurer`
|
|
|
|
|
beans in your Spring config to get access to the `RuntimeWiring.Builder`. The Boot
|
|
|
|
|
starter detects such beans and adds them to <<index#execution-graphqlsource,GraphQlSource.Builder>>.
|
|
|
|
|
|
|
|
|
|
Typically, however, applications will not implement ``DataFetcher`` directly and will
|
|
|
|
|
instead create <<index#controllers,annotated controllers>>. The Boot
|
|
|
|
|
starter declares a `RuntimeWiringConfigurer` called `AnnotatedControllerConfigurer` that
|
|
|
|
|
detects `@Controller` classes with annotated handler methods and registers those as
|
|
|
|
|
``DataFetcher``s.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-runtimewiring-scalar]]
|
|
|
|
|
=== Scalar Types
|
|
|
|
|
|
|
|
|
|
`RuntimeWiringConfigurer` can be used to register custom scalar types:
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes"]
|
|
|
|
|
----
|
|
|
|
|
@Bean
|
|
|
|
|
RuntimeWiringConfigurer runtimeWiringConfigurer() {
|
|
|
|
|
GraphQLScalarType scalarType = ...;
|
|
|
|
|
return (wiringBuilder) -> wiringBuilder.scalar(scalarType);
|
|
|
|
|
}
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-repositories-querydsl]]
|
|
|
|
|
== Querydsl Repositories
|
|
|
|
|
|
|
|
|
|
Spring Data repositories that extend `QuerydslPredicateExecutor` or
|
|
|
|
|
`ReactiveQuerydslPredicateExecutor` and are annotated with `@GraphQlRepository` are
|
|
|
|
|
detected and considered as candidates for `DataFetcher`
|
|
|
|
|
<<index.adoc#data-querydsl-registration,auto registration>> for matching top-level queries.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-repositories-querybyexample]]
|
|
|
|
|
== Query by Example Repositories
|
|
|
|
|
|
|
|
|
|
Spring Data repositories that extend `QueryByExampleExecutor` or
|
|
|
|
|
`ReactiveQueryByExampleExecutor` and are annotated with `@GraphQlRepository` are
|
|
|
|
|
detected and considered as candidates for `DataFetcher`
|
|
|
|
|
<<index.adoc#data-querybyexample-registration,auto registration>> for matching top-level queries.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-web]]
|
|
|
|
|
== Web Endpoints
|
|
|
|
|
|
|
|
|
|
The GraphQL HTTP endpoint is at HTTP POST "/graphql" by default. The path can be customized:
|
|
|
|
|
|
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes"]
|
|
|
|
|
----
|
|
|
|
|
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:
|
|
|
|
|
|
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes"]
|
|
|
|
|
----
|
|
|
|
|
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.path` application property.
|
|
|
|
|
|
|
|
|
|
Declare a `WebInterceptor` bean to have it registered in the
|
|
|
|
|
<<index#web-interception,Web Interception>> for GraphQL over HTTP and WebSocket
|
|
|
|
|
requests.
|
|
|
|
|
|
|
|
|
|
Declare a `ThreadLocalAccessor` bean to assist with the propagation of `ThreadLocal`
|
|
|
|
|
values of interest in <<index.adoc#execution-context-webmvc,Spring MVC>>.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-cors]]
|
|
|
|
|
== CORS
|
|
|
|
|
|
|
|
|
|
{spring-framework-ref-docs}/web.html#mvc-cors[Spring MVC] and
|
|
|
|
|
{spring-framework-ref-docs}/web-reactive.html#webflux-cors[Spring WebFlux] support CORS
|
|
|
|
|
(Cross-Origin Resource Sharing) requests. CORS is a critical part of the web config for
|
|
|
|
|
GraphQL applications that are accessed from browsers using different domains.
|
|
|
|
|
|
|
|
|
|
The Boot starter supports the following CORS properties:
|
|
|
|
|
|
|
|
|
|
[source,properties,indent=0,subs="verbatim"]
|
|
|
|
|
----
|
|
|
|
|
spring.graphql.cors.allowed-origins=https://example.org # Comma-separated list of origins to allow. '*' allows all origins.
|
|
|
|
|
spring.graphql.cors.allowed-origin-patterns= # Comma-separated list of origin patterns like 'https://*.example.com' to allow.
|
|
|
|
|
spring.graphql.cors.allowed-methods=GET,POST # Comma-separated list of methods to allow. '*' allows all methods.
|
|
|
|
|
spring.graphql.cors.allowed-headers= # Comma-separated list of headers to allow in a request. '*' allows all headers.
|
|
|
|
|
spring.graphql.cors.exposed-headers= # Comma-separated list of headers to include in a response.
|
|
|
|
|
spring.graphql.cors.allow-credentials= # Whether credentials are supported. When not set, credentials are not supported.
|
|
|
|
|
spring.graphql.cors.max-age=1800s # How long the response from a pre-flight request can be cached by clients.
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
TIP: For more information about the properties and their meaning, check out the
|
|
|
|
|
{javadoc}/org/springframework/graphql/boot/GraphQlCorsProperties.html[GraphQlCorsProperties Javadoc].
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-exception-handling]]
|
|
|
|
|
== Exceptions
|
|
|
|
|
|
|
|
|
|
Spring GraphQL enables applications to register one or more Spring
|
|
|
|
|
`DataFetcherExceptionResolver` components that are invoked sequentially until one
|
|
|
|
|
resolves the Exception to a list of `graphql.GraphQLError` objects. See
|
|
|
|
|
<<index#execution-exceptions>> for details.
|
|
|
|
|
|
|
|
|
|
The Boot starter detects beans of type `DataFetcherExceptionResolver` and registers them
|
|
|
|
|
automatically with the `GraphQlSource.Builder`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-batch-loader-registry]]
|
|
|
|
|
== BatchLoaderRegistry
|
|
|
|
|
|
|
|
|
|
Spring GraphQL supports the GraphQL Java <<index#execution-batching,batch feature>> and provides
|
|
|
|
|
a `BatchLoaderRegistry` to store registrations of batch loading functions. The Boot
|
|
|
|
|
starter declares a `BatchLoaderRegistry` bean and configures the `ExecutionGraphQlService`
|
|
|
|
|
with it so that applications can simply autowire the registry into their controllers and
|
|
|
|
|
register batch loading functions.
|
|
|
|
|
|
|
|
|
|
For example:
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes"]
|
|
|
|
|
----
|
|
|
|
|
@Controller
|
|
|
|
|
public class BookController {
|
|
|
|
|
|
|
|
|
|
public BookController(BatchLoaderRegistry registry) {
|
|
|
|
|
registry.forTypePair(Long.class, Author.class).registerBatchLoader((authorIds, env) -> {
|
|
|
|
|
// load authors
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@SchemaMapping
|
|
|
|
|
public CompletableFuture<Author> author(Book book, DataLoader<Long, Author> loader) {
|
|
|
|
|
return loader.load(book.getAuthorId());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-graphiql]]
|
|
|
|
|
== GraphiQL
|
|
|
|
|
|
|
|
|
|
The Spring Boot starter includes a https://github.com/graphql/graphiql[GraphiQL] page
|
|
|
|
|
that is exposed at "/graphiql" by default. You can configure this as follows:
|
|
|
|
|
|
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes"]
|
|
|
|
|
----
|
|
|
|
|
spring.graphql.graphiql.enabled=true
|
|
|
|
|
spring.graphql.graphiql.path=/graphiql
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-metrics]]
|
|
|
|
|
== 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:
|
|
|
|
|
|
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes"]
|
|
|
|
|
----
|
|
|
|
|
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:
|
|
|
|
|
|
|
|
|
|
[source,properties,indent=0,subs="verbatim,quotes"]
|
|
|
|
|
----
|
|
|
|
|
management.endpoints.web.exposure.include=health,metrics,info
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-metrics-request-timer]]
|
|
|
|
|
=== Request Timer
|
|
|
|
|
|
|
|
|
|
A Request metric timer is available at `/actuator/metrics/graphql.request`.
|
|
|
|
|
|
|
|
|
|
[cols="1,2,2"]
|
|
|
|
|
|===
|
|
|
|
|
|Tag | Description| Sample values
|
|
|
|
|
|
|
|
|
|
|outcome
|
|
|
|
|
|Request outcome
|
|
|
|
|
|"SUCCESS", "ERROR"
|
|
|
|
|
|===
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-metrics-datafetcher-timer]]
|
|
|
|
|
=== `DataFetcher` Timer
|
|
|
|
|
|
|
|
|
|
A `DataFetcher` metric timer is available at `/actuator/metrics/graphql.datafetcher`.
|
|
|
|
|
|
|
|
|
|
[cols="1,2,2"]
|
|
|
|
|
|===
|
|
|
|
|
|Tag | Description| Sample values
|
|
|
|
|
|
|
|
|
|
|path
|
|
|
|
|
|data fetcher path
|
|
|
|
|
|"Query.project"
|
|
|
|
|
|
|
|
|
|
|outcome
|
|
|
|
|
|data fetching outcome
|
|
|
|
|
|"SUCCESS", "ERROR"
|
|
|
|
|
|===
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-metrics-datafetcher-summary]]
|
|
|
|
|
=== `DataFetcher` Distribution Summary
|
|
|
|
|
|
|
|
|
|
A https://micrometer.io/docs/concepts#_distribution_summaries[distribution summary]
|
|
|
|
|
that counts the number of non-trivial `DataFetcher` calls made per request.
|
|
|
|
|
This metric is useful for detecting "N+1" data fetching issues and consider batch loading;
|
|
|
|
|
it provides the `"TOTAL"` number of data fetcher calls made over the `"COUNT"` of recorded requests,
|
|
|
|
|
as well as the `"MAX"` calls made for a single request over the considered period.
|
|
|
|
|
|
|
|
|
|
The distribution is available at `/actuator/metrics/graphql.request.datafetch.count`.
|
|
|
|
|
|
|
|
|
|
More options are available for
|
|
|
|
|
{spring-boot-ref-docs}/application-properties.html#application-properties.actuator.management.metrics.distribution.maximum-expected-value[configuring distributions with application properties].
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-metrics-error-counter]]
|
|
|
|
|
=== Error Counter
|
|
|
|
|
|
|
|
|
|
A GraphQL error metric counter is available at `/actuator/metrics/graphql.error`.
|
|
|
|
|
|
|
|
|
|
[cols="1,2,2"]
|
|
|
|
|
|===
|
|
|
|
|
|Tag | Description| Sample values
|
|
|
|
|
|
|
|
|
|
|errorType
|
|
|
|
|
|error type
|
|
|
|
|
|"DataFetchingException"
|
|
|
|
|
|
|
|
|
|
|errorPath
|
|
|
|
|
|error JSON Path
|
|
|
|
|
|"$.project"
|
|
|
|
|
|===
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-testing]]
|
|
|
|
|
== Testing
|
|
|
|
|
|
|
|
|
|
Spring GraphQL offers many ways to test your application: with or without a live server,
|
|
|
|
|
with a Web client or without, with a Web transport or testing directly against the
|
|
|
|
|
GraphQL Java engine. Tests rely on <<testing#testing-webgraphqltester,WebGraphQlTester>>, so be
|
|
|
|
|
sure to become familiar with using it.
|
|
|
|
|
|
|
|
|
|
The Spring Boot starter will help you to configure the testing infrastructure; to start,
|
|
|
|
|
add the following to your classpath:
|
|
|
|
|
|
|
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes",role="primary"]
|
|
|
|
|
.Gradle
|
|
|
|
|
----
|
|
|
|
|
dependencies {
|
|
|
|
|
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
|
|
|
|
testImplementation 'org.springframework.graphql:spring-graphql-test:{spring-graphql-version}'
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
}
|
|
|
|
|
----
|
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes",role="secondary"]
|
|
|
|
|
.Maven
|
|
|
|
|
----
|
|
|
|
|
<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>{spring-graphql-version}</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>
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
The following sections cover a range of options for testing a Spring GraphQL application.
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-testing-graphqltest]]
|
|
|
|
|
=== GraphQL Slice Tests
|
|
|
|
|
|
|
|
|
|
Use `@GraphQlTest` on a test class to create GraphQL tests focused on GraphQL request
|
|
|
|
|
execution, without involving a Web layer, and loading only a subset of the application
|
|
|
|
|
configuration.
|
|
|
|
|
|
|
|
|
|
By default, `@GraphQlTest` limits scanning to the following beans:
|
|
|
|
|
|
|
|
|
|
- `@Controller`
|
|
|
|
|
- `RuntimeWiringConfigurer`
|
|
|
|
|
- `JsonComponent`
|
|
|
|
|
- `Converter`
|
|
|
|
|
- `GenericConverter`
|
|
|
|
|
|
|
|
|
|
Use the `controllers` attribute of `@GraphQlTest` to specify a controller class, or to
|
|
|
|
|
list all data controllers required to perform requests in a test class. Leaving it empty,
|
|
|
|
|
includes all controllers.
|
|
|
|
|
|
|
|
|
|
To add collaborator and/or other components to a test class, use one of the following:
|
|
|
|
|
|
|
|
|
|
- `@MockBean` fields in the test class.
|
|
|
|
|
- `@Import` an `@Configuration` class into the test class.
|
|
|
|
|
- Create a `@TestConfiguration` nested class.
|
|
|
|
|
- Broaden the component scan via `includeFilters` on `@GraphQlTest`.
|
|
|
|
|
|
|
|
|
|
To add properties, use the `properties` attribute of `@GraphQlTest`, or add
|
|
|
|
|
`@EnableConfigurationProperties` on the test class.
|
|
|
|
|
|
|
|
|
|
[NOTE]
|
|
|
|
|
====
|
|
|
|
|
`@GraphQlTest` is comparable to
|
|
|
|
|
{spring-boot-ref-docs}/features.html#features.testing.spring-boot-applications.spring-mvc-tests[@WevMvcTest],
|
|
|
|
|
which also uses test "slices" to create focused Web controller tests.
|
|
|
|
|
====
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes"]
|
|
|
|
|
----
|
|
|
|
|
@GraphQlTest(BookController.class)
|
|
|
|
|
public class BookControllerTests {
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private GraphQlTester graphQlTester;
|
|
|
|
|
|
|
|
|
|
@MockBean
|
|
|
|
|
private BookRepository bookRepository;
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void bookdByIdShouldReturnSpringBook() {
|
|
|
|
|
given(this.bookRepository.findById(42L)).willReturn(new Book(42L, "Spring GraphQL"));
|
|
|
|
|
String query = //
|
|
|
|
|
graphQlTester.query(query).execute()
|
|
|
|
|
.path("data.bookById.name").entity(String.class).isEqualTo("Spring GraphQL");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
This mode is useful to test subscriptions without WebSocket.
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes"]
|
|
|
|
|
----
|
|
|
|
|
@GraphQlTest(GreetingController.class)
|
|
|
|
|
public class GreetingControllerTests {
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private GraphQlTester 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();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
`GraphQlService` performS the above request by calling directly the GraphQL Java engine,
|
|
|
|
|
which returns a Reactive Streams `Publisher`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-testing-mock]]
|
|
|
|
|
=== Client and Mock Server Tests
|
|
|
|
|
|
|
|
|
|
You can write fuller integration tests with a Web client and a Web framework, Spring MVC or
|
|
|
|
|
WebFlux, but without running a live server, i.e. using a mock request and response.
|
|
|
|
|
|
|
|
|
|
For GraphQL over HTTP with a {spring-boot-ref-docs}/features.html#features.testing.spring-boot-applications.with-mock-environment[mock server]:
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes"]
|
|
|
|
|
----
|
|
|
|
|
@SpringBootTest
|
|
|
|
|
@AutoConfigureWebGraphQlTester
|
|
|
|
|
public class MockWebGraphQlTests {
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private WebGraphQlTester graphQlTester;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[boot-graphql-testing-live]]
|
|
|
|
|
=== Live Server Tests
|
|
|
|
|
|
|
|
|
|
You can also run tests against the full application infrastructure with a live server.
|
|
|
|
|
Just like {spring-boot-ref-docs}/features.html#features.testing.spring-boot-applications.with-running-server[REST endpoints testing],
|
|
|
|
|
you can use a `WebEnvironment.RANDOM_PORT` environment and test queries using `WebGraphQlTester`.
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes"]
|
|
|
|
|
----
|
|
|
|
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
|
|
|
|
public class MockMvcGraphQlTests {
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private WebGraphQlTester graphQlTester;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
----
|