remove h2 from index.adoc

This commit is contained in:
Rob Winch
2023-07-20 22:13:41 -05:00
committed by Rossen Stoyanchev
parent d485fdf85b
commit 327a3588bc
14 changed files with 201 additions and 232 deletions

View File

@@ -1,10 +1,13 @@
* xref:index.adoc[]
** xref:includes/transports.adoc[]
** xref:includes/request-execution.adoc[]
** xref:includes/data.adoc[]
** xref:includes/controllers.adoc[]
** xref:includes/observability.adoc[]
** xref:includes/graalvm-native.adoc[]
** xref:includes/client.adoc[]
** xref:includes/graphiql.adoc[]
** xref:includes/testing.adoc[]
* xref:index.adoc[Overview]
* xref:transports.adoc[]
* xref:request-execution.adoc[]
* xref:data.adoc[]
* xref:controllers.adoc[]
* xref:security.adoc[]
* xref:observability.adoc[]
* xref:graalvm-native.adoc[]
* xref:client.adoc[]
* xref:graphiql.adoc[]
* xref:testing.adoc[]
* xref:boot-starter.adoc[]
* xref:samples.adoc[]

View File

@@ -0,0 +1,21 @@
[[boot-starter]]
= Boot Starter
Spring Boot provides a starter for building GraphQL applications with Spring for GraphQL.
For version information, see the
https://github.com/spring-projects/spring-graphql/wiki/Spring-for-GraphQL-Versions[Spring for GraphQL Versions] wiki page.
The easiest way to get started is via https://start.spring.io by selecting
"Spring for GraphQL" along with an underlying transport such as Spring MVC of WebFlux over
HTTP or WebSocket, or over RSocket. Refer to the
https://docs.spring.io/spring-boot/docs/current/reference/html/web.html#web.graphql[Spring for GraphQL Starter]
section in the Spring Boot reference for details on supported transports, auto-configuration related
features, and more. For testing support, see
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.testing.spring-boot-applications.spring-graphql-tests[Auto-Configured GraphQL Tests].
For further reference, check the following GraphQL related:
- https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.metrics.supported.spring-graphql[Metrics]
- https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#appendix.application-properties.web[Properties]
- https://docs.spring.io/spring-boot/docs/current/reference/html/auto-configuration-classes.html#appendix.auto-configuration-classes.core[Auto-Configuration Classes]

View File

@@ -16,15 +16,15 @@ build time.
To create a `GraphQlClient` you need one of the following extensions:
- xref:includes/client.adoc#client.httpgraphqlclient[HttpGraphQlClient]
- xref:includes/client.adoc#client.websocketgraphqlclient[WebSocketGraphQlClient]
- xref:includes/client.adoc#client.rsocketgraphqlclient[RSocketGraphQlClient]
- xref:client.adoc#client.httpgraphqlclient[HttpGraphQlClient]
- xref:client.adoc#client.websocketgraphqlclient[WebSocketGraphQlClient]
- xref:client.adoc#client.rsocketgraphqlclient[RSocketGraphQlClient]
Each defines a `Builder` with options relevant to the transport. All builders extend
from a common, base GraphQlClient xref:includes/client.adoc#client.graphqlclient.builder[`Builder`] with options
from a common, base GraphQlClient xref:client.adoc#client.graphqlclient.builder[`Builder`] with options
relevant to all extensions.
Once you have a `GraphQlClient` you can begin to make xref:includes/client.adoc#client.requests[requests].
Once you have a `GraphQlClient` you can begin to make xref:client.adoc#client.requests[requests].
[[client.httpgraphqlclient]]
@@ -41,7 +41,7 @@ HttpGraphQlClient graphQlClient = HttpGraphQlClient.create(webClient);
----
Once `HttpGraphQlClient` is created, you can begin to
xref:includes/client.adoc#client.requests[execute requests] using the same API, independent of the underlying
xref:client.adoc#client.requests[execute requests] using the same API, independent of the underlying
transport. If you need to change any transport specific details, use `mutate()` on an
existing `HttpGraphQlClient` to create a new instance with customized settings:
@@ -97,7 +97,7 @@ single, shared connection for all requests to that server. Each client instance
establishes its own connection and that is typically not the intent for a single server.
Once `WebSocketGraphQlClient` is created, you can begin to
xref:includes/client.adoc#client.requests[execute requests] using the same API, independent of the underlying
xref:client.adoc#client.requests[execute requests] using the same API, independent of the underlying
transport. If you need to change any transport specific details, use `mutate()` on an
existing `WebSocketGraphQlClient` to create a new instance with customized settings:
@@ -149,7 +149,7 @@ For WebSocket transport specific interception, you can create a
}
----
xref:includes/client.adoc#client.interception[Register] the above interceptor as any other
xref:client.adoc#client.interception[Register] the above interceptor as any other
`GraphQlClientInterceptor` and use it also to intercept GraphQL requests, but note there
can be at most one interceptor of type `WebSocketGraphQlClientInterceptor`.
@@ -187,7 +187,7 @@ single, shared session for all requests to that server. Each client instance
establishes its own connection and that is typically not the intent for a single server.
Once `RSocketGraphQlClient` is created, you can begin to
xref:includes/client.adoc#client.requests[execute requests] using the same API, independent of the underlying
xref:client.adoc#client.requests[execute requests] using the same API, independent of the underlying
transport.
@@ -199,7 +199,7 @@ transport.
builders of all extensions. Currently, it has lets you configure:
- `DocumentSource` strategy to load the document for a request from a file
- xref:includes/client.adoc#client.interception[Interception] of executed requests
- xref:client.adoc#client.interception[Interception] of executed requests
@@ -207,8 +207,8 @@ builders of all extensions. Currently, it has lets you configure:
[[client.requests]]
== Requests
Once you have a xref:includes/client.adoc#client.graphqlclient[`GraphQlClient`], you can begin to perform requests via
xref:includes/client.adoc#client.requests.retrieve[retrieve()] or xref:includes/client.adoc#client.requests.execute[execute()]
Once you have a xref:client.adoc#client.graphqlclient[`GraphQlClient`], you can begin to perform requests via
xref:client.adoc#client.requests.retrieve[retrieve()] or xref:client.adoc#client.requests.execute[execute()]
where the former is only a shortcut for the latter.
@@ -239,7 +239,7 @@ The below retrieves and decodes the data for a query:
The input document is a `String` that could be a literal or produced through a code
generated request object. You can also define documents in files and use a
xref:includes/client.adoc#client.requests.document-source[Document Source] to resole them by file name.
xref:client.adoc#client.requests.document-source[Document Source] to resole them by file name.
The path is relative to the "data" key and uses a simple dot (".") separated notation
for nested fields with optional array indices for list elements, e.g. `"project.name"`
@@ -267,7 +267,7 @@ response and the field:
[[client.requests.execute]]
=== Execute
xref:includes/client.adoc#client.requests.retrieve[Retrieve] is only a shortcut to decode from a single path in the
xref:client.adoc#client.requests.retrieve[Retrieve] is only a shortcut to decode from a single path in the
response map. For more control, use the `execute` method and handle the response:
For example:
@@ -341,7 +341,7 @@ You can then:
The "JS GraphQL" plugin for IntelliJ supports GraphQL query files with code completion.
You can use the `GraphQlClient` xref:includes/client.adoc#client.graphqlclient.builder[Builder] to customize the
You can use the `GraphQlClient` xref:client.adoc#client.graphqlclient.builder[Builder] to customize the
`DocumentSource` for loading documents by names.
@@ -352,8 +352,8 @@ You can use the `GraphQlClient` xref:includes/client.adoc#client.graphqlclient.b
`GraphQlClient` can execute subscriptions over transports that support it. Only
the WebSocket and RSocket transports support GraphQL subscriptions, so you'll need to
create a xref:includes/client.adoc#client.websocketgraphqlclient[WebSocketGraphQlClient] or
xref:includes/client.adoc#client.rsocketgraphqlclient[RSocketGraphQlClient].
create a xref:client.adoc#client.websocketgraphqlclient[WebSocketGraphQlClient] or
xref:client.adoc#client.rsocketgraphqlclient[RSocketGraphQlClient].
@@ -361,7 +361,7 @@ xref:includes/client.adoc#client.rsocketgraphqlclient[RSocketGraphQlClient].
=== Retrieve
To start a subscription stream, use `retrieveSubscription` which is similar to
xref:includes/client.adoc#client.requests.retrieve[retrieve] for a single response but returning a stream of
xref:client.adoc#client.requests.retrieve[retrieve] for a single response but returning a stream of
responses, each decoded to some data:
[source,java,indent=0,subs="verbatim,quotes"]
@@ -390,7 +390,7 @@ provides access to the `Subscription`.
[[client.subscriptions.execute]]
=== Execute
xref:includes/client.adoc#client.subscriptions.retrieve[Retrieve] is only a shortcut to decode from a single path in each
xref:client.adoc#client.subscriptions.retrieve[Retrieve] is only a shortcut to decode from a single path in each
response map. For more control, use the `executeSubscription` method and handle each
response directly:

View File

@@ -36,7 +36,7 @@ class, indicating its role as a data fetching component in a GraphQL application
`AnnotatedControllerConfigurer` detects `@Controller` beans and registers their
annotated handler methods as ``DataFetcher``s via `RuntimeWiring.Builder`. It is an
implementation of `RuntimeWiringConfigurer` which can be added to `GraphQlSource.Builder`.
The xref:index.adoc#boot-starter[Boot Starter] automatically declares `AnnotatedControllerConfigurer` as a bean
The xref:boot-starter.adoc[Boot Starter] automatically declares `AnnotatedControllerConfigurer` as a bean
and adds all `RuntimeWiringConfigurer` beans to `GraphQlSource.Builder` and that enables
support for annotated ``DataFetcher``s, see the
{spring-boot-ref-docs}/web.html#web.graphql.runtimewiring[GraphQL RuntimeWiring] section
@@ -136,23 +136,23 @@ Schema mapping handler methods can have any of the following method arguments:
| `@Argument`
| For access to a named field argument bound to a higher-level, typed Object.
See xref:includes/controllers.adoc#controllers.schema-mapping.argument[`@Argument`].
See xref:controllers.adoc#controllers.schema-mapping.argument[`@Argument`].
| `@Argument Map<String, Object>`
| For access to the raw argument value.
See xref:includes/controllers.adoc#controllers.schema-mapping.argument[`@Argument`].
See xref:controllers.adoc#controllers.schema-mapping.argument[`@Argument`].
| `ArgumentValue`
| For access to a named field argument bound to a higher-level, typed Object along
with a flag to indicate if the input argument was omitted vs set to `null`.
See xref:includes/controllers.adoc#controllers.schema-mapping.argument-value[`ArgumentValue`].
See xref:controllers.adoc#controllers.schema-mapping.argument-value[`ArgumentValue`].
| `@Arguments`
| For access to all field arguments bound to a higher-level, typed Object.
See xref:includes/controllers.adoc#controllers.schema-mapping.arguments[`@Arguments`].
See xref:controllers.adoc#controllers.schema-mapping.arguments[`@Arguments`].
| `@Arguments Map<String, Object>`
| For access to the raw map of arguments.
@@ -160,27 +160,27 @@ See xref:includes/controllers.adoc#controllers.schema-mapping.arguments[`@Argume
| `@ProjectedPayload` Interface
| For access to field arguments through a project interface.
See xref:includes/controllers.adoc#controllers.schema-mapping.projectedpayload.argument[`@ProjectedPayload` Interface].
See xref:controllers.adoc#controllers.schema-mapping.projectedpayload.argument[`@ProjectedPayload` Interface].
| "Source"
| For access to the source (i.e. parent/container) instance of the field.
See xref:includes/controllers.adoc#controllers.schema-mapping.source[Source].
See xref:controllers.adoc#controllers.schema-mapping.source[Source].
| `Subrange` and `ScrollSubrange`
| For access to pagination arguments.
See xref:includes/request-execution.adoc#execution.pagination[Pagination], xref:includes/data.adoc#data.pagination.scroll[Scroll], xref:includes/controllers.adoc#controllers.schema-mapping.subrange[`Subrange`].
See xref:request-execution.adoc#execution.pagination[Pagination], xref:data.adoc#data.pagination.scroll[Scroll], xref:controllers.adoc#controllers.schema-mapping.subrange[`Subrange`].
| `Sort`
| For access to sort details.
See xref:includes/request-execution.adoc#execution.pagination[Pagination], xref:includes/controllers.adoc#controllers.schema-mapping.sort[`Sort`].
See xref:request-execution.adoc#execution.pagination[Pagination], xref:controllers.adoc#controllers.schema-mapping.sort[`Sort`].
| `DataLoader`
| For access to a `DataLoader` in the `DataLoaderRegistry`.
See xref:includes/controllers.adoc#controllers.schema-mapping.data-loader[`DataLoader`].
See xref:controllers.adoc#controllers.schema-mapping.data-loader[`DataLoader`].
| `@ContextValue`
| For access to an attribute from the main `GraphQLContext` in `DataFetchingEnvironment`.
@@ -212,7 +212,7 @@ Schema mapping handler methods can return:
- A resolved value of any type.
- `Mono` and `Flux` for asynchronous value(s). Supported for controller methods and for
any `DataFetcher` as described in xref:includes/request-execution.adoc#execution.reactive-datafetcher[Reactive `DataFetcher`].
any `DataFetcher` as described in xref:request-execution.adoc#execution.reactive-datafetcher[Reactive `DataFetcher`].
- `java.util.concurrent.Callable` to have the value(s) produced asynchronously.
For this to work, `AnnotatedControllerConfigurer` must be configured with an `Executor`.
@@ -282,7 +282,7 @@ NOTE: Prior to 1.2, `@Argument Map<String, Object>` returned the full arguments
the annotation did not specify a name. After 1.2, `@Argument` with
`Map<String, Object>` always returns the raw argument value, matching either to the name
specified in the annotation, or to the parameter name. For access to the full arguments
map, please use xref:includes/controllers.adoc#controllers.schema-mapping.arguments[`@Arguments`] instead.
map, please use xref:controllers.adoc#controllers.schema-mapping.arguments[`@Arguments`] instead.
[[controllers.schema-mapping.argument-value]]
@@ -291,7 +291,7 @@ map, please use xref:includes/controllers.adoc#controllers.schema-mapping.argume
By default, input arguments in GraphQL are nullable and optional, which means an argument
can be set to the `null` literal, or not provided at all. This distinction is useful for
partial updates with a mutation where the underlying data may also be, either set to
`null` or not changed at all accordingly. When using xref:includes/controllers.adoc#controllers.schema-mapping.argument[`@Argument`]
`null` or not changed at all accordingly. When using xref:controllers.adoc#controllers.schema-mapping.argument[`@Argument`]
there is no way to make such a distinction, because you would get `null` or an empty
`Optional` in both cases.
@@ -340,7 +340,7 @@ all argument values.
[[controllers.schema-mapping.projectedpayload.argument]]
=== `@ProjectedPayload` Interface
As an alternative to using complete Objects with xref:includes/controllers.adoc#controllers.schema-mapping.argument[`@Argument`],
As an alternative to using complete Objects with xref:controllers.adoc#controllers.schema-mapping.argument[`@Argument`],
you can also use a projection interface to access GraphQL request arguments through a
well-defined, minimal interface. Argument projections are provided by
https://docs.spring.io/spring-data/commons/docs/current/reference/html/#projections.interfaces[Spring Data's Interface projections]
@@ -413,7 +413,7 @@ explicitly specify the type name in the `@SchemaMapping` annotation.
[TIP]
====
A xref:includes/controllers.adoc#controllers.batch-mapping[`@BatchMapping`] handler method can batch load all authors for a query,
A xref:controllers.adoc#controllers.batch-mapping[`@BatchMapping`] handler method can batch load all authors for a query,
given a list of source/parent books objects.
====
@@ -421,7 +421,7 @@ given a list of source/parent books objects.
[[controllers.schema-mapping.subrange]]
=== `Subrange`
When there is a xref:includes/request-execution.adoc#execution.pagination.cursor.strategy[`CursorStrategy`] bean in Spring configuration,
When there is a xref:request-execution.adoc#execution.pagination.cursor.strategy[`CursorStrategy`] bean in Spring configuration,
controller methods support a `Subrange<P>` argument where `<P>` is a relative position
converted from a cursor. For Spring Data, `ScrollSubrange` exposes `ScrollPosition`.
For example:
@@ -441,13 +441,13 @@ public class BookController {
}
----
See xref:includes/request-execution.adoc#execution.pagination[Pagination] for an overview of pagination and of built-in mechanisms.
See xref:request-execution.adoc#execution.pagination[Pagination] for an overview of pagination and of built-in mechanisms.
[[controllers.schema-mapping.sort]]
=== `Sort`
When there is a xref:includes/data.adoc#data.pagination.scroll[SortStrategy] bean in Spring configuration, controller
When there is a xref:data.adoc#data.pagination.scroll[SortStrategy] bean in Spring configuration, controller
methods support `Sort` as a method argument. For example:
[source,java,indent=0,subs="verbatim,quotes"]
@@ -469,7 +469,7 @@ public class BookController {
=== `DataLoader`
When you register a batch loading function for an entity, as explained in
xref:includes/request-execution.adoc#execution.batching[Batch Loading], you can access the `DataLoader` for the entity by declaring a
xref:request-execution.adoc#execution.batching[Batch Loading], you can access the `DataLoader` for the entity by declaring a
method argument of type `DataLoader` and use it to load the entity:
[source,java,indent=0,subs="verbatim,quotes"]
@@ -500,7 +500,7 @@ be necessary.
Note that for many cases with loading related entities, where the `@SchemaMapping` simply
delegates to a `DataLoader`, you can reduce boilerplate by using a
xref:includes/controllers.adoc#controllers.batch-mapping[@BatchMapping] method as described in the next section.
xref:controllers.adoc#controllers.batch-mapping[@BatchMapping] method as described in the next section.
[[controllers.schema-mapping.validation]]
@@ -541,15 +541,15 @@ method invocation:
----
If an error occurs during validation, a `ConstraintViolationException` is raised.
You can use the xref:includes/request-execution.adoc#execution.exceptions[Exceptions] chain to decide how to present that to clients
You can use the xref:request-execution.adoc#execution.exceptions[Exceptions] chain to decide how to present that to clients
by turning it into an error to include in the GraphQL response.
TIP: In addition to `@Valid`, you can also use Spring's `@Validated` that allows
specifying validation groups.
Bean validation is useful for xref:includes/controllers.adoc#controllers.schema-mapping.argument[`@Argument`],
xref:includes/controllers.adoc#controllers.schema-mapping.arguments[`@Arguments`], and
xref:includes/controllers.adoc#controllers.schema-mapping.projectedpayload.argument[@ProjectedPayload]
Bean validation is useful for xref:controllers.adoc#controllers.schema-mapping.argument[`@Argument`],
xref:controllers.adoc#controllers.schema-mapping.arguments[`@Arguments`], and
xref:controllers.adoc#controllers.schema-mapping.projectedpayload.argument[@ProjectedPayload]
method parameters, but applies more generally to any method parameter.
[WARNING]
@@ -566,7 +566,7 @@ for links to relevant issues and a suggested workaround.
[[controllers.batch-mapping]]
== `@BatchMapping`
xref:includes/request-execution.adoc#execution.batching[Batch Loading] addresses the N+1 select problem through the use of an
xref:request-execution.adoc#execution.batching[Batch Loading] addresses the N+1 select problem through the use of an
`org.dataloader.DataLoader` to defer the loading of individual entity instances, so they
can be loaded together. For example:
@@ -679,7 +679,7 @@ Batch mapping methods can return:
== `@GraphQlExceptionHandler`
Use `@GraphQlExceptionHandler` methods to handle exceptions from data fetching with a
flexible xref:includes/controllers.adoc#controllers.exception-handler.signature[method signature]. When declared in a
flexible xref:controllers.adoc#controllers.exception-handler.signature[method signature]. When declared in a
controller, exception handler methods apply to exceptions from the same controller:
[source,java,indent=0,subs="verbatim,quotes"]
@@ -719,7 +719,7 @@ Exception handling via `@GraphQlExceptionHandler` methods is applied automatical
controller invocations. To handle exceptions from other `graphql.schema.DataFetcher`
implementations, not based on controller methods, obtain a
`DataFetcherExceptionResolver` from `AnnotatedControllerConfigurer`, and register it in
`GraphQlSource.Builder` as a xref:includes/request-execution.adoc#execution.exceptions[DataFetcherExceptionResolver].
`GraphQlSource.Builder` as a xref:request-execution.adoc#execution.exceptions[DataFetcherExceptionResolver].
@@ -729,7 +729,7 @@ implementations, not based on controller methods, obtain a
Exception handler methods support a flexible method signature with method arguments
resolved from a `DataFetchingEnvironment,` and matching to those of
xref:includes/controllers.adoc#controllers.schema-mapping.arguments[@SchemaMapping methods].
xref:controllers.adoc#controllers.schema-mapping.arguments[@SchemaMapping methods].
Supported return types are listed below:

View File

@@ -47,7 +47,7 @@ Then use it to create a `DataFetcher`:
----
You can now register the above `DataFetcher` through a
xref:includes/request-execution.adoc#execution.graphqlsource.runtimewiring-configurer[`RuntimeWiringConfigurer`].
xref:request-execution.adoc#execution.graphqlsource.runtimewiring-configurer[`RuntimeWiringConfigurer`].
The `DataFetcher` builds a Querydsl `Predicate` from GraphQL arguments, and uses it to
fetch data. Spring Data supports `QuerydslPredicateExecutor` for JPA, MongoDB, Neo4j, and LDAP.
@@ -140,7 +140,7 @@ each available property. To customize that, you can use `QuerydslDataFetcher` bu
methods to provide a `QuerydslBinderCustomizer`.
A repository may itself be an instance of `QuerydslBinderCustomizer`. This is auto-detected
and transparently applied during xref:includes/data.adoc#data.querydsl.registration[Auto-Registration]. However, when manually
and transparently applied during xref:data.adoc#data.querydsl.registration[Auto-Registration]. However, when manually
building a `QuerydslDataFetcher` you will need to use builder methods to apply it.
`QuerydslDataFetcher` supports interface and DTO projections to transform query results
@@ -148,7 +148,7 @@ before returning these for further GraphQL processing.
TIP: To learn what projections are, please refer to the
https://docs.spring.io/spring-data/commons/docs/current/reference/html/#projections[Spring Data docs].
To understand how to use projections in GraphQL, please see xref:includes/data.adoc#data.projections[Selection Set vs Projections].
To understand how to use projections in GraphQL, please see xref:data.adoc#data.projections[Selection Set vs Projections].
To use Spring Data projections with Querydsl repositories, create either a projection interface
or a target DTO class and configure it through the `projectAs` method to obtain a
@@ -187,7 +187,7 @@ or a target DTO class and configure it through the `projectAs` method to obtain
If a repository is annotated with `@GraphQlRepository`, it is automatically registered
for queries that do not already have a registered `DataFetcher` and whose return type
matches that of the repository domain type. This includes single value queries, multi-value
queries, and xref:includes/request-execution.adoc#execution.pagination[paginated] queries.
queries, and xref:request-execution.adoc#execution.pagination[paginated] queries.
By default, the name of the GraphQL type returned by the query must match the simple name
of the repository domain type. If needed, you can use the `typeName` attribute of
@@ -202,11 +202,11 @@ Auto-registration detects if a given repository implements `QuerydslBinderCustom
transparently applies that through `QuerydslDataFetcher` builder methods.
Auto-registration is performed through a built-in `RuntimeWiringConfigurer` that can be
obtained from `QuerydslDataFetcher`. The xref:index.adoc#boot-starter[Boot Starter] automatically
obtained from `QuerydslDataFetcher`. The xref:boot-starter.adoc[Boot Starter] automatically
detects `@GraphQlRepository` beans and uses them to initialize the
`RuntimeWiringConfigurer` with.
Auto-registration applies xref:includes/data.adoc#data.querybyexample.customizations[customizations]
Auto-registration applies xref:data.adoc#data.querybyexample.customizations[customizations]
by calling `customize(Builder)` on the repository instance if your repository
implements `QuerydslBuilderCustomizer` or `ReactiveQuerydslBuilderCustomizer`
respectively.
@@ -247,7 +247,7 @@ Use `QueryByExampleDataFetcher` to turn the repository into a `DataFetcher`:
----
You can now register the above `DataFetcher` through a
xref:includes/request-execution.adoc#execution.graphqlsource.runtimewiring-configurer[`RuntimeWiringConfigurer`].
xref:request-execution.adoc#execution.graphqlsource.runtimewiring-configurer[`RuntimeWiringConfigurer`].
The `DataFetcher` uses the GraphQL arguments map to create the domain type of the
repository and use that as the example object to fetch data with. Spring Data supports
@@ -276,7 +276,7 @@ results before returning these for further GraphQL processing.
TIP: To learn what projections are, please refer to the
https://docs.spring.io/spring-data/commons/docs/current/reference/html/#projections[Spring Data documentation].
To understand the role of projections in GraphQL, please see xref:includes/data.adoc#data.projections[Selection Set vs Projections].
To understand the role of projections in GraphQL, please see xref:data.adoc#data.projections[Selection Set vs Projections].
To use Spring Data projections with Query by Example repositories, create either a projection interface
or a target DTO class and configure it through the `projectAs` method to obtain a
@@ -314,7 +314,7 @@ or a target DTO class and configure it through the `projectAs` method to obtain
If a repository is annotated with `@GraphQlRepository`, it is automatically registered
for queries that do not already have a registered `DataFetcher` and whose return type
matches that of the repository domain type. This includes single value queries, multi-value
queries, and xref:includes/request-execution.adoc#execution.pagination[paginated] queries.
queries, and xref:request-execution.adoc#execution.pagination[paginated] queries.
By default, the name of the GraphQL type returned by the query must match the simple name
of the repository domain type. If needed, you can use the `typeName` attribute of
@@ -326,11 +326,11 @@ For paginated queries, the simple name of the repository domain type must match
per page.
Auto-registration is performed through a built-in `RuntimeWiringConfigurer` that can be
obtained from `QueryByExampleDataFetcher`. The xref:index.adoc#boot-starter[Boot Starter] automatically
obtained from `QueryByExampleDataFetcher`. The xref:boot-starter.adoc[Boot Starter] automatically
detects `@GraphQlRepository` beans and uses them to initialize the
`RuntimeWiringConfigurer` with.
Auto-registration applies xref:includes/data.adoc#data.querybyexample.customizations[customizations]
Auto-registration applies xref:data.adoc#data.querybyexample.customizations[customizations]
by calling `customize(Builder)` on the repository instance if your repository
implements `QueryByExampleBuilderCustomizer` or
`ReactiveQueryByExampleBuilderCustomizer` respectively.
@@ -359,7 +359,7 @@ aggregate functionality.
In Spring Data you can choose whether you want your aggregate be exposed as is, or
whether to apply transformations to the data model before returning it as a GraphQL
result. Sometimes it's enough to do the former, and by default the
xref:includes/data.adoc#data.querydsl[Querydsl] and the xref:includes/data.adoc#data.querybyexample[Query by Example] integrations turn the GraphQL
xref:data.adoc#data.querydsl[Querydsl] and the xref:data.adoc#data.querybyexample[Query by Example] integrations turn the GraphQL
selection set into property path hints that the underlying Spring Data module uses to
limit the selection.
@@ -394,7 +394,7 @@ required fields (or columns) are part of the database query result.
[[data.pagination.scroll]]
== Scroll
As explained in xref:includes/request-execution.adoc#execution.pagination[Pagination], the GraphQL Cursor Connection spec defines a
As explained in xref:request-execution.adoc#execution.pagination[Pagination], the GraphQL Cursor Connection spec defines a
mechanism for pagination with `Connection`, `Edge`, and `PageInfo` schema types, while
GraphQL Java provides the equivalent Java type representations.
@@ -423,11 +423,11 @@ GraphQlSource.schemaResourceBuilder()
<3> Register the type visitor.
On the request side, a controller method can declare a
xref:includes/controllers.adoc#controllers.schema-mapping.subrange[ScrollSubrange] method argument to paginate forward
or backward. For this to work, you must declare a xref:includes/request-execution.adoc#execution.pagination.cursor.strategy[`CursorStrategy`]
xref:controllers.adoc#controllers.schema-mapping.subrange[ScrollSubrange] method argument to paginate forward
or backward. For this to work, you must declare a xref:request-execution.adoc#execution.pagination.cursor.strategy[`CursorStrategy`]
supports `ScrollPosition` as a bean.
The xref:index.adoc#boot-starter[Boot Starter] declares a `CursorStrategy<ScrollPosition>` bean, and registers the
The xref:boot-starter.adoc[Boot Starter] declares a `CursorStrategy<ScrollPosition>` bean, and registers the
`ConnectionFieldTypeVisitor` as shown above if Spring Data is on the classpath.

View File

@@ -1,10 +1,5 @@
[[spring-for-graphql-documentation]]
= Spring for GraphQL Documentation
Brian Clozel; Andreas Marek; Rossen Stoyanchev; Mark Paluch
[[overview]]
== Overview
= Spring for GraphQL
Spring for GraphQL provides support for Spring applications built on
https://www.graphql-java.com/[GraphQL Java]. It is a joint collaboration between the
@@ -20,92 +15,4 @@ to report a problem, discuss a design issue, or to request a feature.
Check the https://github.com/spring-projects/spring-graphql/wiki[Wiki].
for what's new, baseline requirements, and upgrade notes, and other cross-version information.
To get started, see the xref:index.adoc#boot-starter[Boot Starter] and xref:index.adoc#samples[Samples] sections.
[[security]]
== Security
The path to a xref:includes/transports.adoc#server.transports.http[Web] GraphQL endpoint can be secured with HTTP
URL security to ensure that only authenticated users can access it. This does not,
however, differentiate among different GraphQL requests on such a shared endpoint on
a single URL.
To apply more fine-grained security, add Spring Security annotations such as
`@PreAuthorize` or `@Secured` to service methods involved in fetching specific parts of
the GraphQL response. This should work due to xref:includes/request-execution.adoc#execution.context[Context Propagation] that aims to make
Security, and other context, available at the data fetching level.
The 1.0.x branch of this repository contains samples for
{github-10x-branch}/samples/webmvc-http-security[Spring MVC] and for
{github-10x-branch}/samples/webflux-security[WebFlux].
[[boot-starter]]
== Boot Starter
Spring Boot provides a starter for building GraphQL applications with Spring for GraphQL.
For version information, see the
https://github.com/spring-projects/spring-graphql/wiki/Spring-for-GraphQL-Versions[Spring for GraphQL Versions] wiki page.
The easiest way to get started is via https://start.spring.io by selecting
"Spring for GraphQL" along with an underlying transport such as Spring MVC of WebFlux over
HTTP or WebSocket, or over RSocket. Refer to the
https://docs.spring.io/spring-boot/docs/current/reference/html/web.html#web.graphql[Spring for GraphQL Starter]
section in the Spring Boot reference for details on supported transports, auto-configuration related
features, and more. For testing support, see
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.testing.spring-boot-applications.spring-graphql-tests[Auto-Configured GraphQL Tests].
For further reference, check the following GraphQL related:
- https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.metrics.supported.spring-graphql[Metrics]
- https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#appendix.application-properties.web[Properties]
- https://docs.spring.io/spring-boot/docs/current/reference/html/auto-configuration-classes.html#appendix.auto-configuration-classes.core[Auto-Configuration Classes]
[[samples]]
== Samples
Check out the https://spring.io/guides/gs/graphql-server/["Building a GraphQL service"] Getting Started Guide.
In addition, the 1.0.x branch of this repository contains {github-10x-branch}/samples[sample applications] for various scenarios.
Those samples do not exist in the `main` branch and are planned to be
https://github.com/spring-projects/spring-graphql/issues/208[moved out] into a separate repository.
To run those samples, check out the 1.0.x branch run their main application classes from your IDE,
or from the command line:
[source,bash,indent=0,subs="verbatim,quotes"]
----
$ ./gradlew :samples:{sample-directory-name}:bootRun
----
To get started, see the xref:boot-starter.adoc[Boot Starter] and xref:samples.adoc[Samples] sections.

View File

@@ -2,7 +2,7 @@
= Request Execution
`ExecutionGraphQlService` is the main Spring abstraction to call GraphQL Java to execute
requests. Underlying transports, such as the xref:includes/transports.adoc#server.transports.http[HTTP], delegate to
requests. Underlying transports, such as the xref:transports.adoc#server.transports.http[HTTP], delegate to
`ExecutionGraphQlService` to handle requests.
The main implementation, `DefaultExecutionGraphQlService`, is configured with a
@@ -17,15 +17,15 @@ The main implementation, `DefaultExecutionGraphQlService`, is configured with a
includes a builder API to build that instance. The default builder is available via
`GraphQlSource.schemaResourceBuilder()`.
The xref:index.adoc#boot-starter[Boot Starter] creates an instance of this builder and further initializes it
to xref:includes/request-execution.adoc#execution.graphqlsource.schema-resources[load schema files] from a configurable location,
The xref:boot-starter.adoc[Boot Starter] creates an instance of this builder and further initializes it
to xref:request-execution.adoc#execution.graphqlsource.schema-resources[load schema files] from a configurable location,
to {spring-boot-ref-docs}/application-properties.html#appendix.application-properties.web[expose properties]
to apply to `GraphQlSource.Builder`, to detect
xref:includes/request-execution.adoc#execution.graphqlsource.runtimewiring-configurer[`RuntimeWiringConfigurer`] beans,
xref:request-execution.adoc#execution.graphqlsource.runtimewiring-configurer[`RuntimeWiringConfigurer`] beans,
https://www.graphql-java.com/documentation/instrumentation[Instrumentation] beans for
{spring-boot-ref-docs}/actuator.html#actuator.metrics.supported.spring-graphql[GraphQL metrics],
and `DataFetcherExceptionResolver` and `SubscriptionExceptionResolver` beans for
xref:includes/request-execution.adoc#execution.exceptions[exception resolution]. For further customizations, you can also
xref:request-execution.adoc#execution.exceptions[exception resolution]. For further customizations, you can also
declare a `GraphQlSourceBuilderCustomizer` bean, for example:
[source,java,indent=0,subs="verbatim,quotes"]
@@ -80,7 +80,7 @@ builder.schemaResources(..)
})
----
The xref:includes/request-execution.adoc#execution.graphqlsource[GraphQlSource section] explains how to configure that with Spring Boot.
The xref:request-execution.adoc#execution.graphqlsource[GraphQlSource section] explains how to configure that with Spring Boot.
For an example with Apollo Federation, see
https://github.com/apollographql/federation-jvm-spring-example[federation-jvm-spring-example].
@@ -92,11 +92,11 @@ https://github.com/apollographql/federation-jvm-spring-example[federation-jvm-sp
You can use `RuntimeWiringConfigurer` to register:
- Custom scalar types.
- xref:includes/request-execution.adoc#execution.graphqlsource.directives[Directives] handling code.
- Default xref:includes/request-execution.adoc#execution.graphqlsource.default-type-resolver[`TypeResolver`] for interface and union types.
- `DataFetcher` for a field although applications will typically use xref:includes/controllers.adoc[Annotated Controllers], and
- xref:request-execution.adoc#execution.graphqlsource.directives[Directives] handling code.
- Default xref:request-execution.adoc#execution.graphqlsource.default-type-resolver[`TypeResolver`] for interface and union types.
- `DataFetcher` for a field although applications will typically use xref:controllers.adoc[Annotated Controllers], and
those are detected and registered as ``DataFetcher``s by `AnnotatedControllerConfigurer`,
which is a `RuntimeWiringConfigurer`. The xref:index.adoc#boot-starter[Boot Starter] automatically registers
which is a `RuntimeWiringConfigurer`. The xref:boot-starter.adoc[Boot Starter] automatically registers
`AnnotatedControllerConfigurer`.
NOTE: GraphQL Java, server applications use Jackson only for serialization to and from maps of data.
@@ -104,7 +104,7 @@ Client input is parsed into a map. Server output is assembled into a map based o
This means you can't rely on Jackson serialization/deserialization annotations.
Instead, you can use https://www.graphql-java.com/documentation/scalars/[custom scalar types].
The xref:index.adoc#boot-starter[Boot Starter] detects beans of type `RuntimeWiringConfigurer` and
The xref:boot-starter.adoc[Boot Starter] detects beans of type `RuntimeWiringConfigurer` and
registers them in the `GraphQlSource.Builder`. That means in most cases, you'll' have
something like the following in your configuration:
@@ -139,7 +139,7 @@ number of factories that are then invoked in sequence.
`GraphQlSource.Builder` registers `ClassNameTypeResolver` as the default `TypeResolver`
to use for GraphQL Interfaces and Unions that don't already have such a registration
through a xref:includes/request-execution.adoc#execution.graphqlsource.runtimewiring-configurer[`RuntimeWiringConfigurer`]. The purpose of
through a xref:request-execution.adoc#execution.graphqlsource.runtimewiring-configurer[`RuntimeWiringConfigurer`]. The purpose of
a `TypeResolver` in GraphQL Java is to determine the GraphQL Object type for values
returned from the `DataFetcher` for a GraphQL Interface or Union field.
@@ -159,7 +159,7 @@ classNameTypeResolver.setClassNameExtractor((klass) -> {
builder.defaultTypeResolver(classNameTypeResolver);
----
The xref:includes/request-execution.adoc#execution.graphqlsource[GraphQlSource section] explains how to configure that with Spring Boot.
The xref:request-execution.adoc#execution.graphqlsource[GraphQlSource section] explains how to configure that with Spring Boot.
[[execution.graphqlsource.directives]]
@@ -175,7 +175,7 @@ and handle directives. For more details, see
GraphQL Java documentation.
In Spring GraphQL you can register a `SchemaDirectiveWiring` through a
xref:includes/request-execution.adoc#execution.graphqlsource.runtimewiring-configurer[`RuntimeWiringConfigurer`]. The xref:index.adoc#boot-starter[Boot Starter] detects
xref:request-execution.adoc#execution.graphqlsource.runtimewiring-configurer[`RuntimeWiringConfigurer`]. The xref:boot-starter.adoc[Boot Starter] detects
such beans, so you might have something like:
[source,java,indent=0,subs="verbatim,quotes"]
@@ -202,7 +202,7 @@ library.
You can register a `graphql.schema.GraphQLTypeVisitor` via
`builder.schemaResources(..).typeVisitorsToTransformSchema(..)` if you want to traverse
and transform the schema after it is created, and make changes to the schema. Keep in mind
that this is more expensive than xref:includes/request-execution.adoc#execution.graphqlsource.schema-traversal[Schema Traversal] so generally
that this is more expensive than xref:request-execution.adoc#execution.graphqlsource.schema-traversal[Schema Traversal] so generally
prefer traversal to transformation unless you need to make schema changes.
@@ -213,7 +213,7 @@ You can register a `graphql.schema.GraphQLTypeVisitor` via
`builder.schemaResources(..).typeVisitors(..)` if you want to traverse the schema after
it is created, and possibly apply changes to the `GraphQLCodeRegistry`. Keep in mind,
however, that such a visitor cannot change the schema. See
xref:includes/request-execution.adoc#execution.graphqlsource.schema-transformation[Schema Transformation], if you need to make changes to the schema.
xref:request-execution.adoc#execution.graphqlsource.schema-transformation[Schema Transformation], if you need to make changes to the schema.
[[execution.graphqlsource.schema-mapping-inspection]]
@@ -234,8 +234,8 @@ structure.
Spring for GraphQL defines the `SelfDescribingDataFetcher` interface to allow a
`DataFetcher` to expose return type information. All Spring `DataFetcher` implementations
implement this interface. That includes those for xref:includes/controllers.adoc[Annotated Controllers], and those for
xref:includes/data.adoc#data.querydsl[Querydsl] and xref:includes/data.adoc#data.querybyexample[Query by Example] Spring Data repositories. For annotated
implement this interface. That includes those for xref:controllers.adoc[Annotated Controllers], and those for
xref:data.adoc#data.querydsl[Querydsl] and xref:data.adoc#data.querybyexample[Query by Example] Spring Data repositories. For annotated
controllers, the return type is derived from the declared return type on a
`@SchemaMapping` method.
@@ -315,7 +315,7 @@ builder.schemaResources(..)
.configureGraphQl(graphQLBuilder -> graphQLBuilder.preparsedDocumentProvider(provider))
----
The xref:includes/request-execution.adoc#execution.graphqlsource[GraphQlSource section] explains how to configure that with Spring Boot.
The xref:request-execution.adoc#execution.graphqlsource[GraphQlSource section] explains how to configure that with Spring Boot.
@@ -330,7 +330,7 @@ GraphQL responses.
A reactive `DataFetcher` can rely on access to Reactor context propagated from the
transport layer, such as from a WebFlux request handling, see
xref:includes/request-execution.adoc#execution.context.webflux[WebFlux Context].
xref:request-execution.adoc#execution.context.webflux[WebFlux Context].
@@ -338,7 +338,7 @@ xref:includes/request-execution.adoc#execution.context.webflux[WebFlux Context].
== Context Propagation
Spring for GraphQL provides support to transparently propagate context from the
xref:includes/transports.adoc#server.transports.http[HTTP], through GraphQL Java, and to `DataFetcher` and other components it
xref:transports.adoc#server.transports.http[HTTP], through GraphQL Java, and to `DataFetcher` and other components it
invokes. This includes both `ThreadLocal` context from the Spring MVC request handling
thread and Reactor `Context` from the WebFlux processing pipeline.
@@ -348,7 +348,7 @@ thread and Reactor `Context` from the WebFlux processing pipeline.
A `DataFetcher` and other components invoked by GraphQL Java may not always execute on
the same thread as the Spring MVC handler, for example if an asynchronous
xref:includes/transports.adoc#server.interception[`WebGraphQlInterceptor`] or `DataFetcher` switches to a
xref:transports.adoc#server.interception[`WebGraphQlInterceptor`] or `DataFetcher` switches to a
different thread.
Spring for GraphQL supports propagating `ThreadLocal` values from the Servlet container
@@ -392,9 +392,9 @@ automatically through the `java.util.ServiceLoader` mechanism.
[[execution.context.webflux]]
=== WebFlux
A xref:includes/request-execution.adoc#execution.reactive-datafetcher[Reactive `DataFetcher`] can rely on access to Reactor context that
A xref:request-execution.adoc#execution.reactive-datafetcher[Reactive `DataFetcher`] can rely on access to Reactor context that
originates from the WebFlux request handling chain. This includes Reactor context
added by xref:includes/transports.adoc#server.interception[WebGraphQlInterceptor] components.
added by xref:transports.adoc#server.interception[WebGraphQlInterceptor] components.
@@ -407,16 +407,16 @@ single handler only.
Spring for GraphQL registers a `DataFetcherExceptionHandler` that provides default
handling and enables the `DataFetcherExceptionResolver` contract. An application can
register any number of resolvers via xref:includes/request-execution.adoc#execution.graphqlsource[`GraphQLSource`] builder and those are in
register any number of resolvers via xref:request-execution.adoc#execution.graphqlsource[`GraphQLSource`] builder and those are in
order until one them resolves the `Exception` to a `List<graphql.GraphQLError>`.
The Spring Boot starter detects beans of this type.
`DataFetcherExceptionResolverAdapter` is a convenient base class with protected methods
`resolveToSingleError` and `resolveToMultipleErrors`.
The xref:includes/controllers.adoc[Annotated Controllers] programming model enables handling data fetching exceptions with
The xref:controllers.adoc[Annotated Controllers] programming model enables handling data fetching exceptions with
annotated exception handler methods with a flexible method signature, see
xref:includes/controllers.adoc#controllers.exception-handler[`@GraphQlExceptionHandler`] for details.
xref:controllers.adoc#controllers.exception-handler[`@GraphQlExceptionHandler`] for details.
A `GraphQLError` can be assigned to a category based on the GraphQL Java
`graphql.ErrorClassification`, or the Spring GraphQL `ErrorType`, which defines the following:
@@ -448,7 +448,7 @@ having a field path.
`DataFetcherExceptionResolver` cannot handle such global errors because they are raised
before execution begins and before any `DataFetcher` is invoked. An application can use
transport level interceptors to inspect and transform errors in the `ExecutionResult`.
See examples under xref:includes/transports.adoc#server.interception.web[`WebGraphQlInterceptor`].
See examples under xref:transports.adoc#server.interception.web[`WebGraphQlInterceptor`].
[[execution.exceptions.subscription]]
@@ -537,13 +537,13 @@ and the following type definitions will be transparently added to the schema:
}
----
The xref:index.adoc#boot-starter[Boot Starter] registers `ConnectionTypeDefinitionConfigurer` by default.
The xref:boot-starter.adoc[Boot Starter] registers `ConnectionTypeDefinitionConfigurer` by default.
[[execution.pagination.adapters]]
=== `ConnectionAdapter`
Once xref:includes/request-execution.adoc#execution.pagination.types[Connection Types] are available in the schema, you also need
Once xref:request-execution.adoc#execution.pagination.types[Connection Types] are available in the schema, you also need
equivalent Java types. GraphQL Java provides those, including generic `Connection` and
`Edge`, as well as a `PageInfo`.
@@ -571,11 +571,11 @@ GraphQlSource.schemaResourceBuilder()
<1> Create type visitor with one or more ``ConnectionAdapter``s.
<2> Resister the type visitor.
There are xref:includes/data.adoc#data.pagination.scroll[built-in] ``ConnectionAdapter``s for Spring Data's
There are xref:data.adoc#data.pagination.scroll[built-in] ``ConnectionAdapter``s for Spring Data's
`Window` and `Slice`. You can also create your own custom adapter. `ConnectionAdapter`
implementations rely on a xref:includes/request-execution.adoc#execution.pagination.cursor.strategy[`CursorStrategy`] to
implementations rely on a xref:request-execution.adoc#execution.pagination.cursor.strategy[`CursorStrategy`] to
create cursors for returned items. The same strategy is also used to support the
xref:includes/controllers.adoc#controllers.schema-mapping.subrange[`Subrange`] controller method argument that contains
xref:controllers.adoc#controllers.schema-mapping.subrange[`Subrange`] controller method argument that contains
pagination input.
@@ -586,16 +586,16 @@ pagination input.
position of an item within a large result set. The cursor can be based on an index or
on a keyset.
A xref:includes/request-execution.adoc#execution.pagination.adapters[`ConnectionAdapter`] uses this to encode cursors for returned items.
xref:includes/controllers.adoc[Annotated Controllers] methods, xref:includes/data.adoc#data.querydsl[Querydsl] repositories, and xref:includes/data.adoc#data.querybyexample[Query by Example]
A xref:request-execution.adoc#execution.pagination.adapters[`ConnectionAdapter`] uses this to encode cursors for returned items.
xref:controllers.adoc[Annotated Controllers] methods, xref:data.adoc#data.querydsl[Querydsl] repositories, and xref:data.adoc#data.querybyexample[Query by Example]
repositories use it to decode cursors from pagination requests, and create a `Subrange`.
`CursorEncoder` is a related contract that further encodes and decodes String cursors to
make them opaque to clients. `EncodingCursorStrategy` combines `CursorStrategy` with a
`CursorEncoder`. You can use `Base64CursorEncoder`, `NoOpEncoder` or create your own.
There is a xref:includes/data.adoc#data.pagination.scroll[built-in] `CursorStrategy` for the Spring Data
`ScrollPosition`. The xref:index.adoc#boot-starter[Boot Starter] registers a `CursorStrategy<ScrollPosition>` with
There is a xref:data.adoc#data.pagination.scroll[built-in] `CursorStrategy` for the Spring Data
`ScrollPosition`. The xref:boot-starter.adoc[Boot Starter] registers a `CursorStrategy<ScrollPosition>` with
`Base64Encoder` when Spring Data is present.
@@ -606,7 +606,7 @@ There is no standard way to provide sort information in a GraphQL request. Howev
pagination depends on a stable sort order. You can use a default order, or otherwise
expose input types and extract sort details from GraphQL arguments.
There is xref:includes/data.adoc#data.pagination.sort[built-in] support for Spring Data's `Sort` as a controller
There is xref:data.adoc#data.pagination.sort[built-in] support for Spring Data's `Sort` as a controller
method argument. For this to work, you need to have a `SortStrategy` bean.
@@ -663,14 +663,14 @@ public class MyConfig {
}
----
The xref:index.adoc#boot-starter[Boot Starter] declares a `BatchLoaderRegistry` bean that you can inject into
The xref:boot-starter.adoc[Boot Starter] declares a `BatchLoaderRegistry` bean that you can inject into
your configuration, as shown above, or into any component such as a controller in order
register batch loading functions. In turn the `BatchLoaderRegistry` is injected into
`DefaultExecutionGraphQlService` where it ensures `DataLoader` registrations per request.
By default, the `DataLoader` name is based on the class name of the target entity.
This allows an `@SchemaMapping` method to declare a
xref:includes/controllers.adoc#controllers.schema-mapping.data-loader[DataLoader argument] with a generic type, and
xref:controllers.adoc#controllers.schema-mapping.data-loader[DataLoader argument] with a generic type, and
without the need for specifying a name. The name, however, can be customized through the
`BatchLoaderRegistry` builder, if necessary, along with other `DataLoaderOptions`.
@@ -679,12 +679,12 @@ registration, you can override Boot's `BatchLoaderRegistry` bean and use the con
for `DefaultBatchLoaderRegistry` that accepts `Supplier<DataLoaderOptions>`.
For many cases, when loading related entities, you can use
xref:includes/controllers.adoc#controllers.batch-mapping[@BatchMapping] controller methods, which are a shortcut
xref:controllers.adoc#controllers.batch-mapping[@BatchMapping] controller methods, which are a shortcut
for and replace the need to use `BatchLoaderRegistry` and `DataLoader` directly.
`BatchLoaderRegistry` provides other important benefits too. It supports access to
the same `GraphQLContext` from batch loading functions and from `@BatchMapping` methods,
as well as ensures xref:includes/request-execution.adoc#execution.context[Context Propagation] to them. This is why applications are expected
as well as ensures xref:request-execution.adoc#execution.context[Context Propagation] to them. This is why applications are expected
to use it. It is possible to perform your own `DataLoader` registrations directly but
such registrations would forgo the above benefits.

View File

@@ -0,0 +1,15 @@
[[samples]]
= Samples
Check out the https://spring.io/guides/gs/graphql-server/["Building a GraphQL service"] Getting Started Guide.
In addition, the 1.0.x branch of this repository contains {github-10x-branch}/samples[sample applications] for various scenarios.
Those samples do not exist in the `main` branch and are planned to be
https://github.com/spring-projects/spring-graphql/issues/208[moved out] into a separate repository.
To run those samples, check out the 1.0.x branch run their main application classes from your IDE,
or from the command line:
[source,bash,indent=0,subs="verbatim,quotes"]
----
$ ./gradlew :samples:{sample-directory-name}:bootRun
----

View File

@@ -0,0 +1,23 @@
[[security]]
= Security
The path to a xref:transports.adoc#server.transports.http[Web] GraphQL endpoint can be secured with HTTP
URL security to ensure that only authenticated users can access it. This does not,
however, differentiate among different GraphQL requests on such a shared endpoint on
a single URL.
To apply more fine-grained security, add Spring Security annotations such as
`@PreAuthorize` or `@Secured` to service methods involved in fetching specific parts of
the GraphQL response. This should work due to xref:request-execution.adoc#execution.context[Context Propagation] that aims to make
Security, and other context, available at the data fetching level.
The 1.0.x branch of this repository contains samples for
{github-10x-branch}/samples/webmvc-http-security[Spring MVC] and for
{github-10x-branch}/samples/webflux-security[WebFlux].

View File

@@ -42,17 +42,17 @@ specific is configured at build time.
To create a `GraphQlTester` that performs requests through a client, you need one of the
following extensions:
- xref:includes/testing.adoc#testing.httpgraphqltester[HttpGraphQlTester]
- xref:includes/testing.adoc#testing.websocketgraphqltester[WebSocketGraphQlTester]
- xref:includes/testing.adoc#testing.rsocketgraphqltester[RSocketGraphQlTester]
- xref:testing.adoc#testing.httpgraphqltester[HttpGraphQlTester]
- xref:testing.adoc#testing.websocketgraphqltester[WebSocketGraphQlTester]
- xref:testing.adoc#testing.rsocketgraphqltester[RSocketGraphQlTester]
To create a `GraphQlTester` that performs tests on the server side, without a client:
- xref:includes/testing.adoc#testing.graphqlservicetester[ExecutionGraphQlServiceTester]
- xref:includes/testing.adoc#testing.webgraphqltester[WebGraphQlServiceTester]
- xref:testing.adoc#testing.graphqlservicetester[ExecutionGraphQlServiceTester]
- xref:testing.adoc#testing.webgraphqltester[WebGraphQlServiceTester]
Each defines a `Builder` with options relevant to the transport. All builders extend
from a common, base GraphQlTester xref:includes/testing.adoc#testing.graphqltester.builder[`Builder`] with
from a common, base GraphQlTester xref:testing.adoc#testing.graphqltester.builder[`Builder`] with
options relevant to all extensions.
@@ -109,7 +109,7 @@ Or to test against a live server running on a port:
----
Once `HttpGraphQlTester` is created, you can begin to
xref:includes/testing.adoc#testing.requests[execute requests] using the same API, independent of the underlying
xref:testing.adoc#testing.requests[execute requests] using the same API, independent of the underlying
transport. If you need to change any transport specific details, use `mutate()` on an
existing `HttpSocketGraphQlTester` to create a new instance with customized settings:
@@ -152,7 +152,7 @@ its own single, shared connection for all requests. Typically, you'll want to us
instance only per server.
Once `WebSocketGraphQlTester` is created, you can begin to
xref:includes/testing.adoc#testing.requests[execute requests] using the same API, independent of the underlying
xref:testing.adoc#testing.requests[execute requests] using the same API, independent of the underlying
transport. If you need to change any transport specific details, use `mutate()` on an
existing `WebSocketGraphQlTester` to create a new instance with customized settings:
@@ -202,7 +202,7 @@ instance only per server. You can use the `stop()` method on the tester to close
session explicitly.
Once `RSocketGraphQlTester` is created, you can begin to
xref:includes/testing.adoc#testing.requests[execute requests] using the same API, independent of the underlying
xref:testing.adoc#testing.requests[execute requests] using the same API, independent of the underlying
transport.
@@ -220,7 +220,7 @@ client to send requests over a transport protocol. To test directly against a
----
Once `ExecutionGraphQlServiceTester` is created, you can begin to
xref:includes/testing.adoc#testing.requests[execute requests] using the same API, independent of the underlying
xref:testing.adoc#testing.requests[execute requests] using the same API, independent of the underlying
transport.
`ExecutionGraphQlServiceTester.Builder` provides an option to customize `ExecutionInput` details:
@@ -238,7 +238,7 @@ transport.
[[testing.webgraphqltester]]
=== `WebGraphQlHandler`
The xref:includes/testing.adoc#testing.graphqlservicetester[`GraphQlService`] extension lets you test on the server side, without
The xref:testing.adoc#testing.graphqlservicetester[`GraphQlService`] extension lets you test on the server side, without
a client. However, in some cases it's useful to involve server side transport
handling with given mock transport input.
@@ -264,7 +264,7 @@ The builder for this extension allows you to define HTTP request details:
----
Once `WebGraphQlServiceTester` is created, you can begin to
xref:includes/testing.adoc#testing.requests[execute requests] using the same API, independent of the underlying
xref:testing.adoc#testing.requests[execute requests] using the same API, independent of the underlying
transport.
@@ -355,7 +355,7 @@ instead of `execute` to verify there are no errors in the response:
graphQlTester.query(query).executeAndVerify();
----
See xref:includes/testing.adoc#testing.errors[Errors] for more details on error handling.
See xref:testing.adoc#testing.errors[Errors] for more details on error handling.
@@ -399,9 +399,9 @@ of responses and then use `StepVerifier` from Project Reactor to inspect the str
.verifyComplete();
----
Subscriptions are supported only with xref:includes/testing.adoc#testing.websocketgraphqltester[WebSocketGraphQlTester]
Subscriptions are supported only with xref:testing.adoc#testing.websocketgraphqltester[WebSocketGraphQlTester]
, or with the server side
xref:includes/testing.adoc#testing.graphqlservicetester[`GraphQlService`] and xref:includes/testing.adoc#testing.webgraphqltester[`WebGraphQlHandler`] extensions.
xref:testing.adoc#testing.graphqlservicetester[`GraphQlService`] and xref:testing.adoc#testing.webgraphqltester[`WebGraphQlHandler`] extensions.

View File

@@ -9,7 +9,7 @@ RSocket.
== HTTP
`GraphQlHttpHandler` handles GraphQL over HTTP requests and delegates to the
xref:includes/transports.adoc#server.interception[Interception] chain for request execution. There are two variants, one for
xref:transports.adoc#server.interception[Interception] chain for request execution. There are two variants, one for
Spring MVC and one for Spring WebFlux. Both handle requests asynchronously and have
equivalent functionality, but rely on blocking vs non-blocking I/O respectively for
writing the HTTP response.
@@ -24,7 +24,7 @@ is also supported, as described in the specification.
`GraphQlHttpHandler` can be exposed as an HTTP endpoint by declaring a `RouterFunction`
bean and using the `RouterFunctions` from Spring MVC or WebFlux to create the route. The
xref:index.adoc#boot-starter[Boot Starter] does this, see the
xref:boot-starter.adoc[Boot Starter] does this, see the
{spring-boot-ref-docs}/web.html#web.graphql.transports.http-websocket[Web Endpoints] section for
details, or check `GraphQlWebMvcAutoConfiguration` or `GraphQlWebFluxAutoConfiguration`
it contains, for the actual config.
@@ -59,7 +59,7 @@ https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md[protocol] define
https://github.com/enisdenjo/graphql-ws[graphql-ws] library. The main reason to use
GraphQL over WebSocket is subscriptions which allow sending a stream of GraphQL
responses, but it can also be used for regular queries with a single response.
The handler delegates every request to the xref:includes/transports.adoc#server.interception[Interception] chain for further
The handler delegates every request to the xref:transports.adoc#server.interception[Interception] chain for further
request execution.
[TIP]
@@ -84,7 +84,7 @@ https://github.com/enisdenjo/graphql-ws#recipes[recipes] for client use.
`GraphQlWebSocketHandler` can be exposed as a WebSocket endpoint by declaring a
`SimpleUrlHandlerMapping` bean and using it to map the handler to a URL path. By default,
the xref:index.adoc#boot-starter[Boot Starter] does not expose a GraphQL over WebSocket endpoint, but it's easy to
the xref:boot-starter.adoc[Boot Starter] does not expose a GraphQL over WebSocket endpoint, but it's easy to
enable it by adding a property for the endpoint path. Please, see the
{spring-boot-ref-docs}/web.html#web.graphql.transports.http-websocket[Web Endpoints]
section for details, or check the `GraphQlWebMvcAutoConfiguration` or the
@@ -120,7 +120,7 @@ called to process a request.
[[server.interception.web]]
=== `WebGraphQlInterceptor`
xref:includes/transports.adoc#server.transports.http[HTTP] and xref:includes/transports.adoc#server.transports.websocket[WebSocket] transports invoke a chain of
xref:transports.adoc#server.transports.http[HTTP] and xref:transports.adoc#server.transports.websocket[WebSocket] transports invoke a chain of
0 or more `WebGraphQlInterceptor`, followed by an `ExecutionGraphQlService` that calls
the GraphQL Java engine. `WebGraphQlInterceptor` allows an application to intercept
incoming requests and do one of the following:
@@ -152,13 +152,13 @@ include-code:RequestErrorInterceptor[]
<3> Update the `ExecutionResult` with the modified errors
Use `WebGraphQlHandler` to configure the `WebGraphQlInterceptor` chain. This is supported
by the xref:index.adoc#boot-starter[Boot Starter], see
by the xref:boot-starter.adoc[Boot Starter], see
{spring-boot-ref-docs}/web.html#web.graphql.transports.http-websocket[Web Endpoints].
[[server.interception.rsocket]]
=== `RSocketQlInterceptor`
Similar to xref:includes/transports.adoc#server.interception.web[`WebGraphQlInterceptor`], an `RSocketQlInterceptor` allows intercepting
Similar to xref:transports.adoc#server.interception.web[`WebGraphQlInterceptor`], an `RSocketQlInterceptor` allows intercepting
GraphQL over RSocket requests before and after GraphQL Java engine execution. You can use
this to customize the `graphql.ExecutionInput` and the `graphql.ExecutionResult`.