Rewrite anchors in reference documentation

This commit ensures that all anchors in the reference documentation
follow a `"section.sub.title"`-like pattern to better align with the
spring-asciidoctor-backends best practices. This will allow an easier
integration with code snippets.

All rewritten anchors are listed in the anchor-rewrite.properties file
for automatic redirection.
This commit is contained in:
Brian Clozel
2022-12-06 14:39:45 +01:00
parent 0458f15ddd
commit 70afadc04a
6 changed files with 249 additions and 187 deletions

View File

@@ -0,0 +1,68 @@
server-transports=server.transports
server-http=server.transports.http
server-websocket=server.transports.websocket
server-rsocket=server.transports.rsocket
execution-graphqlsource=execution.graphqlsource
execution-graphqlsource-schema-resources=execution.graphqlsource.schema-resources
execution-graphqlsource-schema-creation=execution.graphqlsource.schema-creation
execution-graphqlsource-schema-traversal=execution.graphqlsource.schema-traversal
execution-graphqlsource-schema-transformation=execution.graphqlsource.schema-transformation
execution-graphqlsource-runtimewiring-configurer=execution.graphqlsource.runtimewiring-configurer
execution-graphqlsource-default-type-resolver=execution.graphqlsource.default-type-resolver
execution-graphqlsource-operation-caching=execution.graphqlsource.operation-caching
execution-graphqlsource-directives=execution.graphqlsource.directives
execution-reactive-datafetcher=execution.reactive-datafetcher
execution-context=execution.context
execution-context-webmvc=execution.context.webmvc
execution-context-webflux=execution.context.webflux
execution-exceptions=execution.exceptions
execution-exceptions-request=execution.exceptions.request
execution-exceptions-subsctiption=execution.exceptions.subscription
execution-batching=execution.batching
execution-batching-dataloader=execution.batching.dataloader
execution-batching-batch-loader-registry=execution.batching.batch-loader-registry
execution-batching-testing=execution.batching.testing
data-querydsl=data.querydsl
data-querydsl-build=data.querydsl.build
data-querydsl-customizations=data.querydsl.customizations
data-querydsl-registration=data.querydsl.registration
data-querybyexample=data.querybyexample
data-querybyexample-build=data.querybyexample.build
data-querybyexample-customizations=data.querybyexample.customizations
data-querybyexample-registration=data.querybyexample.registration
data-projections=data.projections
controllers-schema-mapping=controllers.schema-mapping
controllers-schema-mapping-signature=controllers.schema-mapping.signature
controllers-schema-mapping-argument=controllers.schema-mapping.argument
controllers-schema-mapping-argument-value=controllers.schema-mapping.argument-value
controllers-schema-mapping-arguments=controllers.schema-mapping.arguments
controllers-schema-mapping-projectedpayload-argument=controllers.schema-mapping.projectedpayload.argument
controllers-schema-mapping-source=controllers.schema-mapping.source
controllers-schema-mapping-data-loader=controllers.schema-mapping.data-loader
controllers-schema-mapping-validation=controllers.schema-mapping.validation
controllers-batch-mapping=controllers.batch-mapping
controllers-batch-mapping-signature=controllers.batch-mapping.signature
client-graphqlclient=client.graphqlclient
client-httpgraphqlclient=client.httpgraphqlclient
client-websocketgraphqlclient=client.websocketgraphqlclient
client-websocketgraphqlclient-interceptor=client.websocketgraphqlclient.interceptor
client-rsocketgraphqlclient=client.rsocketgraphqlclient
client-graphqlclient-builder=client.graphqlclient.builder
client-requests=client.requests
client-requests-retrieve=client.requests.retrieve
client-requests-execute=client.requests.execute
client-requests-document-source=client.requests.document-source
client-subscriptions=client.subscriptions
client-subscriptions-retrieve=client.subscriptions.retrieve
client-subscriptions-execute=client.subscriptions.execute
client-interception=client.interception
testing-graphqltester=testing.graphqltester
testing-httpgraphqltester=testing.httpgraphqltester
testing-websocketgraphqltester=testing.websocketgraphqltester
testing-rsocketgraphqltester=testing.rsocketgraphqltester
testing-graphqlservicetester=testing.graphqlservicetester
testing-webgraphqltester=testing.webgraphqltester
testing-graphqltester-builder=testing.graphqltester.builder
testing-requests=testing.requests
testing-subscriptions=testing.subscriptions
testing-errors=testing.errors

View File

@@ -1,22 +1,26 @@
:chomp: default headers packages
:docs-site: https://docs.spring.io
:idprefix:
:idseparator: -
:toc: left
:toclevels: 4
:tabsize: 4
:idseparator: -
:toc: left
:toclevels: 4
:tabsize: 4
:numbered:
:sectanchors:
:sectnums:
:hide-uri-scheme:
:github-tag: main
:github-repo: spring-projects/spring-graphql
:github-raw: https://raw.githubusercontent.com/{github-repo}/{github-tag}
:github-issues: https://github.com/{github-repo}/issues/
:github-main-branch: https://github.com/{github-repo}/tree/main
:github-10x-branch: https://github.com/{github-repo}/tree/1.0.x
:github-wiki: https://github.com/{github-repo}/wiki
:graphql-java-docs: https://www.graphql-java.com/documentation
:javadoc: https://docs.spring.io/spring-graphql/docs/{spring-graphql-version}/api
:spring-framework-ref-docs: https://docs.spring.io/spring-framework/docs/current/reference/html
:docs-java: {docdir}/../../main/java/org/springframework/graphql/docs
:docs-kotlin: {docdir}/../../main/kotlin/org/springframework/graphql/docs
:docs-resources: {docdir}/../../main/resources
:github-tag: main
:github-repo: spring-projects/spring-graphql
:github-raw: https://raw.githubusercontent.com/{github-repo}/{github-tag}
:github-issues: https://github.com/{github-repo}/issues/
:github-main-branch: https://github.com/{github-repo}/tree/main
:github-10x-branch: https://github.com/{github-repo}/tree/1.0.x
:github-wiki: https://github.com/{github-repo}/wiki
:graphql-java-docs: https://www.graphql-java.com/documentation
:javadoc: https://docs.spring.io/spring-graphql/docs/{spring-graphql-version}/api
:spring-framework-ref-docs: https://docs.spring.io/spring-framework/docs/current/reference/html
// {spring-boot-version} attribute from build.gradle
:spring-boot-ref-docs: https://docs.spring.io/spring-boot/docs/{spring-boot-version}/reference/html
:spring-boot-ref-docs: https://docs.spring.io/spring-boot/docs/{spring-boot-version}/reference/html

View File

@@ -1,8 +1,3 @@
include::attributes.adoc[]
[[client]]
= Client
@@ -11,7 +6,7 @@ WebSocket, and RSocket.
[[client-graphqlclient]]
[[client.graphqlclient]]
== `GraphQlClient`
`GraphQlClient` is a contract that declares a common workflow for GraphQL requests that is
@@ -21,18 +16,18 @@ build time.
To create a `GraphQlClient` you need one of the following extensions:
- <<client-httpgraphqlclient, HttpGraphQlClient>>
- <<client-websocketgraphqlclient, WebSocketGraphQlClient>>
- <<client-rsocketgraphqlclient, RSocketGraphQlClient>>
- <<client.httpgraphqlclient, HttpGraphQlClient>>
- <<client.websocketgraphqlclient, WebSocketGraphQlClient>>
- <<client.rsocketgraphqlclient, RSocketGraphQlClient>>
Each defines a `Builder` with options relevant to the transport. All builders extend
from a common, base GraphQlClient <<client-graphqlclient-builder, `Builder`>> with options
from a common, base GraphQlClient <<client.graphqlclient.builder, `Builder`>> with options
relevant to all extensions.
Once you have a `GraphQlClient` you can begin to make <<client-requests, requests>>.
Once you have a `GraphQlClient` you can begin to make <<client.requests, requests>>.
[[client-httpgraphqlclient]]
[[client.httpgraphqlclient]]
=== HTTP
`HttpGraphQlClient` uses
@@ -46,7 +41,7 @@ HttpGraphQlClient graphQlClient = HttpGraphQlClient.create(webClient);
----
Once `HttpGraphQlClient` is created, you can begin to
<<client-requests, execute requests>> using the same API, independent of the underlying
<<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:
@@ -70,7 +65,7 @@ existing `HttpGraphQlClient` to create a new instance with customized settings:
[[client-websocketgraphqlclient]]
[[client.websocketgraphqlclient]]
=== WebSocket
`WebSocketGraphQlClient` executes GraphQL requests over a shared WebSocket connection.
@@ -102,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
<<client-requests, execute requests>> using the same API, independent of the underlying
<<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:
@@ -126,7 +121,7 @@ existing `WebSocketGraphQlClient` to create a new instance with customized setti
----
[[client-websocketgraphqlclient-interceptor]]
[[client.websocketgraphqlclient.interceptor]]
==== Interceptor
The https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md[GraphQL over WebSocket]
@@ -154,13 +149,13 @@ For WebSocket transport specific interception, you can create a
}
----
<<client-interception,Register>> the above interceptor as any other
<<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`.
[[client-rsocketgraphqlclient]]
[[client.rsocketgraphqlclient]]
=== RSocket
`RSocketGraphQlClient` uses
@@ -192,33 +187,33 @@ 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
<<client-requests, execute requests>> using the same API, independent of the underlying
<<client.requests, execute requests>> using the same API, independent of the underlying
transport.
[[client-graphqlclient-builder]]
[[client.graphqlclient.builder]]
=== Builder
`GraphQlClient` defines a parent `Builder` with common configuration options for the
builders of all extensions. Currently, it has lets you configure:
- `DocumentSource` strategy to load the document for a request from a file
- <<client-interception>> of executed requests
- <<client.interception>> of executed requests
[[client-requests]]
[[client.requests]]
== Requests
Once you have a <<client-graphqlclient>>, you can begin to perform requests via
<<client-requests-retrieve, retrieve()>> or <<client-requests-execute, execute()>>
Once you have a <<client.graphqlclient>>, you can begin to perform requests via
<<client.requests.retrieve, retrieve()>> or <<client.requests.execute, execute()>>
where the former is only a shortcut for the latter.
[[client-requests-retrieve]]
[[client.requests.retrieve]]
=== Retrieve
The below retrieves and decodes the data for a query:
@@ -244,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
<<client-requests-document-source>> to resole them by file name.
<<client.requests.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"`
@@ -269,10 +264,10 @@ response and the field:
[[client-requests-execute]]
[[client.requests.execute]]
=== Execute
<<client-requests-retrieve>> is only a shortcut to decode from a single path in the
<<client.requests.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:
@@ -307,7 +302,7 @@ For example:
[[client-requests-document-source]]
[[client.requests.document-source]]
=== Document Source
The document for a request is a `String` that may be defined in a local variable or
@@ -346,26 +341,26 @@ You can then:
The "JS GraphQL" plugin for IntelliJ supports GraphQL query files with code completion.
You can use the `GraphQlClient` <<client-graphqlclient-builder>> to customize the
You can use the `GraphQlClient` <<client.graphqlclient.builder>> to customize the
`DocumentSource` for loading documents by names.
[[client-subscriptions]]
[[client.subscriptions]]
== Subscription Requests
`GraphQlClient` can execute subscriptions over transports that support it. Currently, only
the WebSocket transport supports GraphQL streams, so you'll need to create a
<<client-websocketgraphqlclient,WebSocketGraphQlClient>>.
<<client.websocketgraphqlclient,WebSocketGraphQlClient>>.
[[client-subscriptions-retrieve]]
[[client.subscriptions.retrieve]]
=== Retrieve
To start a subscription stream, use `retrieveSubscription` which is similar to
<<client-requests-retrieve,retrieve>> for a single response but returning a stream of
<<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"]
@@ -389,10 +384,10 @@ the connection and start the subscription again.
[[client-subscriptions-execute]]
[[client.subscriptions.execute]]
=== Execute
<<client-subscriptions-retrieve>> is only a shortcut to decode from a single path in each
<<client.subscriptions.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:
@@ -422,7 +417,7 @@ response directly:
[[client-interception]]
[[client.interception]]
== Interception
You create a `GraphQlClientInterceptor` to intercept all requests through a client:

View File

@@ -1,8 +1,3 @@
include::attributes.adoc[]
[[testing]]
= Testing
@@ -36,7 +31,7 @@ dependencies {
[[testing-graphqltester]]
[[testing.graphqltester]]
== `GraphQlTester`
`GraphQlTester` is a contract that declares a common workflow for testing GraphQL
@@ -47,22 +42,22 @@ specific is configured at build time.
To create a `GraphQlTester` that performs requests through a client, you need one of the
following extensions:
- <<testing-httpgraphqltester, HttpGraphQlTester>>
- <<testing-websocketgraphqltester, WebSocketGraphQlTester>>
- <<testing-rsocketgraphqltester, RSocketGraphQlTester>>
- <<testing.httpgraphqltester, HttpGraphQlTester>>
- <<testing.websocketgraphqltester, WebSocketGraphQlTester>>
- <<testing.rsocketgraphqltester, RSocketGraphQlTester>>
To create a `GraphQlTester` that performs tests on the server side, without a client:
- <<testing-graphqlservicetester, ExecutionGraphQlServiceTester>>
- <<testing-webgraphqltester, WebGraphQlServiceTester>>
- <<testing.graphqlservicetester, ExecutionGraphQlServiceTester>>
- <<testing.webgraphqltester, WebGraphQlServiceTester>>
Each defines a `Builder` with options relevant to the transport. All builders extend
from a common, base GraphQlTester <<testing-graphqltester-builder, `Builder`>> with
from a common, base GraphQlTester <<testing.graphqltester.builder, `Builder`>> with
options relevant to all extensions.
[[testing-httpgraphqltester]]
[[testing.httpgraphqltester]]
=== HTTP
`HttpGraphQlTester` uses
@@ -114,7 +109,7 @@ Or to test against a live server running on a port:
----
Once `HttpGraphQlTester` is created, you can begin to
<<testing-requests, execute requests>> using the same API, independent of the underlying
<<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:
@@ -136,7 +131,7 @@ existing `HttpSocketGraphQlTester` to create a new instance with customized sett
[[testing-websocketgraphqltester]]
[[testing.websocketgraphqltester]]
=== WebSocket
`WebSocketGraphQlTester` executes GraphQL requests over a shared WebSocket connection.
@@ -157,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
<<testing-requests, execute requests>> using the same API, independent of the underlying
<<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:
@@ -185,7 +180,7 @@ connection closed, e.g. after a test runs.
[[testing-rsocketgraphqltester]]
[[testing.rsocketgraphqltester]]
=== RSocket
`RSocketGraphQlTester` uses `RSocketRequester` from spring-messaging to execute GraphQL
@@ -207,11 +202,11 @@ 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
<<testing-requests, execute requests>> using the same API, independent of the underlying
<<testing.requests, execute requests>> using the same API, independent of the underlying
transport.
[[testing-graphqlservicetester]]
[[testing.graphqlservicetester]]
=== `GraphQlService`
Many times it's enough to test GraphQL requests on the server side, without the use of a
@@ -225,14 +220,14 @@ client to send requests over a transport protocol. To test directly against a
----
Once `ExecutionGraphQlServiceTester` is created, you can begin to
<<testing-requests, execute requests>> using the same API, independent of the underlying
<<testing.requests, execute requests>> using the same API, independent of the underlying
transport.
[[testing-webgraphqltester]]
[[testing.webgraphqltester]]
=== `WebGraphQlHandler`
The <<testing-graphqlservicetester>> extension lets you test on the server side, without
The <<testing.graphqlservicetester>> 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.
@@ -258,12 +253,12 @@ The builder for this extension allows you to define HTTP request details:
----
Once `WebGraphQlServiceTester` is created, you can begin to
<<testing-requests, execute requests>> using the same API, independent of the underlying
<<testing.requests, execute requests>> using the same API, independent of the underlying
transport.
[[testing-graphqltester-builder]]
[[testing.graphqltester.builder]]
=== Builder
`GraphQlTester` defines a parent `Builder` with common configuration options for the
@@ -279,7 +274,7 @@ out.
[[testing-requests]]
[[testing.requests]]
== Requests
Once you have a `GraphQlTester`, you can begin to test requests. The below executes a
@@ -349,12 +344,12 @@ instead of `execute` to verify there are no errors in the response:
graphQlTester.query(query).executeAndVerify();
----
See <<testing-errors>> for more details on error handling.
See <<testing.errors>> for more details on error handling.
[[testing-subscriptions]]
[[testing.subscriptions]]
== Subscriptions
To test subscriptions, call `executeSubscription` instead of `execute` to obtain a stream
@@ -373,13 +368,13 @@ of responses and then use `StepVerifier` from Project Reactor to inspect the str
.verifyComplete();
----
Subscriptions are supported only with <<testing-websocketgraphqltester,
Subscriptions are supported only with <<testing.websocketgraphqltester,
WebSocketGraphQlTester>>, or with the server side
<<testing-graphqlservicetester>> and <<testing-webgraphqltester>> extensions.
<<testing.graphqlservicetester>> and <<testing.webgraphqltester>> extensions.
[[testing-errors]]
[[testing.errors]]
== Errors
When you use `verify()`, any errors under the "errors" key in the response will cause

View File

@@ -27,18 +27,18 @@ The are also https://github.com/spring-projects/spring-graphql/tree/1.0.x/sample
[[server-transports]]
[[server.transports]]
== Server Transports
Spring for GraphQL supports server handling of GraphQL requests over HTTP, WebSocket, and
RSocket.
[[server-http]]
[[server.transports.http]]
=== HTTP
`GraphQlHttpHandler` handles GraphQL over HTTP requests and delegates to the
<<server-interception>> chain for request execution. There are two variants, one for
<<server.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.
@@ -64,7 +64,7 @@ The 1.0.x branch of this repository contains a Spring MVC
[[server-websocket]]
[[server.transports.websocket]]
=== WebSocket
`GraphQlWebSocketHandler` handles GraphQL over WebSocket requests based on the
@@ -72,7 +72,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 <<server-interception>> chain for further
The handler delegates every request to the <<server.interception>> chain for further
request execution.
[TIP]
@@ -108,7 +108,7 @@ The 1.0.x branch of this repository contains a WebFlux
[[server-rsocket]]
[[server.transports.rsocket]]
=== RSocket
`GraphQlRSocketHandler` handles GraphQL over RSocket requests. Queries and mutations are
@@ -145,17 +145,17 @@ public class GraphQlRSocketController {
[[server-interception]]
[[server.interception]]
=== Interception
Server transports allow intercepting requests before and after the GraphQL Java engine is
called to process a request.
[[server-interception-web]]
[[server.interception.web]]
==== `WebGraphQlInterceptor`
<<server-http>> and <<server-websocket>> transports invoke a chain of
<<server.transports.http>> and <<server.transports.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:
@@ -259,10 +259,10 @@ by the Boot starter, see
{spring-boot-ref-docs}/web.html#web.graphql.transports.http-websocket[Web Endpoints].
[[server-interception-rsocket]]
[[server.interception.rsocket]]
==== `RSocketQlInterceptor`
Similar to <<server-interception-web>>, an `RSocketQlInterceptor` allows intercepting
Similar to <<server.interception.web>>, 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`.
@@ -273,7 +273,7 @@ this to customize the `graphql.ExecutionInput` and the `graphql.ExecutionResult`
== Request Execution
`ExecutionGraphQlService` is the main Spring abstraction to call GraphQL Java to execute
requests. Underlying transports, such as the <<server-transports>>, delegate to
requests. Underlying transports, such as the <<server.transports.http>>, delegate to
`ExecutionGraphQlService` to handle requests.
The main implementation, `DefaultExecutionGraphQlService`, is configured with a
@@ -281,7 +281,7 @@ The main implementation, `DefaultExecutionGraphQlService`, is configured with a
[[execution-graphqlsource]]
[[execution.graphqlsource]]
=== `GraphQLSource`
`GraphQlSource` is a contract to expose the `graphql.GraphQL` instance to use that also
@@ -290,14 +290,14 @@ includes a builder API to build that instance. The default builder is available
{spring-boot-ref-docs}/web.html#web.graphql[Spring Boot starter] creates an instance of
this builder and further initializes it as follows:
- Loads <<execution-graphqlsource-schema-resources, schema files>> from a configurable location.
- Loads <<execution.graphqlsource.schema-resources, schema files>> from a configurable location.
- Exposes {spring-boot-ref-docs}/application-properties.html#appendix.application-properties.web[properties]
that apply to `GraphQlSource.Builder`.
- Detects <<execution-graphqlsource-runtimewiring-configurer>> beans.
- Detects <<execution.graphqlsource.runtimewiring-configurer>> beans.
- Detects https://www.graphql-java.com/documentation/instrumentation[Instrumentation] beans for
{spring-boot-ref-docs}/actuator.html#actuator.metrics.supported.spring-graphql[GraphQL metrics].
- Detects `DataFetcherExceptionResolver` beans for <<execution-exceptions, exception resolution>>.
- Detects `SubscriptionExceptionResolver` beans for <<execution-exceptions-subsctiption, subscription exception resolution>>.
- Detects `DataFetcherExceptionResolver` beans for <<execution.exceptions, exception resolution>>.
- Detects `SubscriptionExceptionResolver` beans for <<execution.exceptions.subscription, subscription exception resolution>>.
For further customizations, you can declare a `GraphQlSourceBuilderCustomizer` bean. For example, to
configure your own `ExecutionIdProvider`:
@@ -318,7 +318,7 @@ class GraphQlConfig {
[[execution-graphqlsource-schema-resources]]
[[execution.graphqlsource.schema-resources]]
==== Schema Resources
`GraphQlSource.Builder` can be configured with one or more `Resource` instances to be
@@ -336,7 +336,7 @@ TIP: Use `classpath*:graphql/**/` to find schema files across multiple classpath
locations, e.g. across multiple modules.
[[execution-graphqlsource-schema-creation]]
[[execution.graphqlsource.schema-creation]]
==== Schema Creation
By default, `GraphQlSource.Builder` uses the GraphQL Java `SchemaGenerator` to create the
@@ -354,30 +354,30 @@ builder.schemaResources(..)
})
----
The <<execution-graphqlsource, GraphQlSource section>> explains how to configure that with Spring Boot.
The <<execution.graphqlsource, GraphQlSource section>> explains how to configure that with Spring Boot.
[[execution-graphqlsource-schema-traversal]]
[[execution.graphqlsource.schema-traversal]]
==== Schema Traversal
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
<<execution-graphqlsource-schema-transformation>>, if you need to make changes to the schema.
<<execution.graphqlsource.schema-transformation>>, if you need to make changes to the schema.
[[execution-graphqlsource-schema-transformation]]
[[execution.graphqlsource.schema-transformation]]
==== Schema Transformation
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 <<execution-graphqlsource-schema-traversal>> so generally
that this is more expensive than <<execution.graphqlsource.schema-traversal>> so generally
prefer traversal to transformation unless you need to make schema changes.
[[execution-graphqlsource-runtimewiring-configurer]]
[[execution.graphqlsource.runtimewiring-configurer]]
==== `RuntimeWiringConfigurer`
You can use `RuntimeWiringConfigurer` to register:
@@ -385,7 +385,7 @@ You can use `RuntimeWiringConfigurer` to register:
- Custom scalar types.
- Directives handling code.
- `TypeResolver`, if you need to override the
<<execution-graphqlsource-default-type-resolver>> for a type.
<<execution.graphqlsource.default-type-resolver>> for a type.
- `DataFetcher` for a field, although most applications will simply configure
`AnnotatedControllerConfigurer`, which detects annotated, `DataFetcher` handler methods.
The Spring Boot starter adds the `AnnotatedControllerConfigurer` by default.
@@ -423,12 +423,12 @@ schema definitions, implement the alternative `configure` method that accepts bo
number of factories that are then invoked in sequence.
[[execution-graphqlsource-default-type-resolver]]
[[execution.graphqlsource.default-type-resolver]]
==== Default `TypeResolver`
`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 <<execution-graphqlsource-runtimewiring-configurer>>. The purpose of
through a <<execution.graphqlsource.runtimewiring-configurer>>. 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.
@@ -448,9 +448,9 @@ classNameTypeResolver.setClassNameExtractor((klass) -> {
builder.defaultTypeResolver(classNameTypeResolver);
----
The <<execution-graphqlsource, GraphQlSource section>> explains how to configure that with Spring Boot.
The <<execution.graphqlsource, GraphQlSource section>> explains how to configure that with Spring Boot.
[[execution-graphqlsource-operation-caching]]
[[execution.graphqlsource.operation-caching]]
==== Operation Caching
GraphQL Java must _parse_ and _validate_ an operation before executing it. This may impact
@@ -476,9 +476,9 @@ builder.schemaResources(..)
.configureGraphQl(graphQLBuilder -> graphQLBuilder.preparsedDocumentProvider(provider))
----
The <<execution-graphqlsource, GraphQlSource section>> explains how to configure that with Spring Boot.
The <<execution.graphqlsource, GraphQlSource section>> explains how to configure that with Spring Boot.
[[execution-graphqlsource-directives]]
[[execution.graphqlsource.directives]]
==== Directives
The GraphQL language supports directives that "describe alternate runtime execution and
@@ -491,7 +491,7 @@ and handle directives. For more details, see
GraphQL Java documentation.
In Spring GraphQL you can register a `SchemaDirectiveWiring` through a
<<execution-graphqlsource-runtimewiring-configurer>>. The Spring Boot starter detects
<<execution.graphqlsource.runtimewiring-configurer>>. The Spring Boot starter detects
such beans, so you might have something like:
[source,java,indent=0,subs="verbatim,quotes"]
@@ -513,7 +513,7 @@ library.
[[execution-reactive-datafetcher]]
[[execution.reactive-datafetcher]]
=== Reactive `DataFetcher`
The default `GraphQlSource` builder enables support for a `DataFetcher` to return `Mono`
@@ -524,25 +524,25 @@ 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
<<execution-context-webflux, WebFlux Context>>.
<<execution.context.webflux, WebFlux Context>>.
[[execution-context]]
[[execution.context]]
=== Context Propagation
Spring for GraphQL provides support to transparently propagate context from the
<<server-transports>>, through GraphQL Java, and to `DataFetcher` and other components it
<<server.transports.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.
[[execution-context-webmvc]]
[[execution.context.webmvc]]
==== WebMvc
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
<<server-interception, `WebGraphQlInterceptor`>> or `DataFetcher` switches to a
<<server.interception, `WebGraphQlInterceptor`>> or `DataFetcher` switches to a
different thread.
Spring for GraphQL supports propagating `ThreadLocal` values from the Servlet container
@@ -583,23 +583,23 @@ You can register a `ThreadLocalAccessor` manually on startup with the global
automatically through the `java.util.ServiceLoader` mechanism.
[[execution-context-webflux]]
[[execution.context.webflux]]
==== WebFlux
A <<execution-reactive-datafetcher>> can rely on access to Reactor context that
A <<execution.reactive-datafetcher>> can rely on access to Reactor context that
originates from the WebFlux request handling chain. This includes Reactor context
added by <<server-interception, WebGraphQlInterceptor>> components.
added by <<server.interception, WebGraphQlInterceptor>> components.
[[execution-exceptions]]
[[execution.exceptions]]
=== Exception Resolution
A GraphQL Java application can register a `DataFetcherExceptionHandler` to decide how to
represent exceptions from the data layer in the "errors" section of the GraphQL response.
Spring for GraphQL has a built-in `DataFetcherExceptionHandler` that is configured for use
by the default <<execution-graphqlsource>> builder. It allows applications to register
by the default <<execution.graphqlsource>> builder. It allows applications to register
one or more Spring `DataFetcherExceptionResolver` components that are invoked sequentially
until one resolves the `Exception` to a (possibly empty) list of `graphql.GraphQLError`
objects.
@@ -628,7 +628,7 @@ error details.
Unresolved exception are logged at ERROR level along with the `executionId` to correlate
to the error sent to the client. Resolved exceptions are logged at DEBUG level.
[[execution-exceptions-request]]
[[execution.exceptions.request]]
==== Request Exceptions
The GraphQL Java engine may run into validation or other errors when parsing the request
@@ -639,10 +639,10 @@ 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 <<server-interception-web>>.
See examples under <<server.interception.web>>.
[[execution-exceptions-subsctiption]]
[[execution.exceptions.subscription]]
==== Subscription Exceptions
The `Publisher` for a subscription request may complete with an error signal in which case
@@ -659,7 +659,7 @@ to send to the client.
[[execution-batching]]
[[execution.batching]]
=== Batch Loading
Given a `Book` and its `Author`, we can create one `DataFetcher` for a book and another
@@ -669,7 +669,7 @@ books as the author for each book is loaded individually. This is known as the N
problem.
[[execution-batching-dataloader]]
[[execution.batching.dataloader]]
==== `DataLoader`
GraphQL Java provides a `DataLoader` mechanism for batch loading of related entities.
@@ -684,7 +684,7 @@ summary of how it works:
improve efficiency.
[[execution-batching-batch-loader-registry]]
[[execution.batching.batch-loader-registry]]
==== `BatchLoaderRegistry`
The complete batching loading mechanism in GraphQL Java requires implementing one of
@@ -719,7 +719,7 @@ register batch loading functions. In turn the `BatchLoaderRegistry` is injected
By default, the `DataLoader` name is based on the class name of the target entity.
This allows an `@SchemaMapping` method to declare a
<<controllers-schema-mapping-data-loader,DataLoader argument>> with a generic type, and
<<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`.
@@ -728,17 +728,17 @@ 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
<<controllers-batch-mapping,@BatchMapping>> controller methods, which are a shortcut
<<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 <<execution-context>> to them. This is why applications are expected
as well as ensures <<execution.context>> 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.
[[execution-batching-testing]]
[[execution.batching.testing]]
==== Testing Batch Loading
Start by having `BatchLoaderRegistry` perform registrations on a `DataLoaderRegistry`:
@@ -782,7 +782,7 @@ with `@GraphQlRepository`.
[[data-querydsl]]
[[data.querydsl]]
=== Querydsl
Spring for GraphQL supports use of http://www.querydsl.com/[Querydsl] to fetch data through
@@ -814,7 +814,7 @@ Then use it to create a `DataFetcher`:
----
You can now register the above `DataFetcher` through a
<<execution-graphqlsource-runtimewiring-configurer>>.
<<execution.graphqlsource.runtimewiring-configurer>>.
The `DataFetcher` builds a Querydsl `Predicate` from GraphQL request parameters, and
uses it to fetch data. Spring Data supports `QuerydslPredicateExecutor` for JPA,
@@ -825,7 +825,7 @@ If the repository is `ReactiveQuerydslPredicateExecutor`, the builder returns
variant for MongoDB.
[[data-querydsl-build]]
[[data.querydsl.build]]
==== Build Setup
To configure Querydsl in your build, follow the
@@ -896,7 +896,7 @@ The {github-10x-branch}/samples/webmvc-http[webmvc-http] sample uses Querydsl fo
`artifactRepositories`.
[[data-querydsl-customizations]]
[[data.querydsl.customizations]]
==== Customizations
`QuerydslDataFetcher` supports customizing how GraphQL arguments are bound onto properties
@@ -905,7 +905,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 <<data-querydsl-registration>>. However, when manually
and transparently applied during <<data.querydsl.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
@@ -913,7 +913,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 <<data-projections>>.
To understand how to use projections in GraphQL, please see <<data.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
@@ -946,7 +946,7 @@ or a target DTO class and configure it through the `projectAs` method to obtain
[[data-querydsl-registration]]
[[data.querydsl.registration]]
==== Auto-Registration
If a repository is annotated with `@GraphQlRepository`, it is automatically registered
@@ -967,13 +967,13 @@ obtained from `QuerydslDataFetcher`. The
detects `@GraphQlRepository` beans and uses them to initialize the
`RuntimeWiringConfigurer` with.
Auto-registration applies <<data-querybyexample-customizations, customizations>>
Auto-registration applies <<data.querybyexample.customizations, customizations>>
by calling `customize(Builder)` on the repository instance if your repository
implements `QuerydslBuilderCustomizer` or `ReactiveQuerydslBuilderCustomizer`
respectively.
[[data-querybyexample]]
[[data.querybyexample]]
=== Query by Example
Spring Data supports the use of
@@ -1004,7 +1004,7 @@ Use `QueryByExampleDataFetcher` to turn the repository into a `DataFetcher`:
----
You can now register the above `DataFetcher` through a
<<execution-graphqlsource-runtimewiring-configurer>>.
<<execution.graphqlsource.runtimewiring-configurer>>.
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
@@ -1015,14 +1015,14 @@ If the repository is `ReactiveQueryByExampleExecutor`, the builder returns
variant for MongoDB, Neo4j, Redis, and R2dbc.
[[data-querybyexample-build]]
[[data.querybyexample.build]]
==== Build Setup
Query by Example is already included in the Spring Data modules for the data stores where
it is supported, so no extra setup is required to enable it.
[[data-querybyexample-customizations]]
[[data.querybyexample.customizations]]
==== Customizations
`QueryByExampleDataFetcher` supports interface and DTO projections to transform query
@@ -1030,7 +1030,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 <<data-projections>>.
To understand the role of projections in GraphQL, please see <<data.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
@@ -1062,7 +1062,7 @@ or a target DTO class and configure it through the `projectAs` method to obtain
----
[[data-querybyexample-registration]]
[[data.querybyexample.registration]]
==== Auto-Registration
If a repository is annotated with `@GraphQlRepository`, it is automatically registered
@@ -1080,14 +1080,14 @@ obtained from `QueryByExampleDataFetcher`. The
detects `@GraphQlRepository` beans and uses them to initialize the
`RuntimeWiringConfigurer` with.
Auto-registration applies <<data-querybyexample-customizations, customizations>>
Auto-registration applies <<data.querybyexample.customizations, customizations>>
by calling `customize(Builder)` on the repository instance if your repository
implements `QueryByExampleBuilderCustomizer` or
`ReactiveQueryByExampleBuilderCustomizer` respectively.
[[data-projections]]
[[data.projections]]
=== Selection Set vs Projections
A common question that arises is, how GraphQL selection sets compare to
@@ -1109,7 +1109,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
<<data-querydsl>> and the <<data-querybyexample>> integrations turn the GraphQL
<<data.querydsl>> and the <<data.querybyexample>> integrations turn the GraphQL
selection set into property path hints that the underlying Spring Data module uses to
limit the selection.
@@ -1187,7 +1187,7 @@ support for annotated ``DataFetcher``s, see the
in the Boot starter documentation.
[[controllers-schema-mapping]]
[[controllers.schema-mapping]]
=== `@SchemaMapping`
The `@SchemaMapping` annotation maps a handler method to a field in the GraphQL schema
@@ -1268,7 +1268,7 @@ for fields under the Query, Mutation, and Subscription types respectively. For e
method arguments and return values..
[[controllers-schema-mapping-signature]]
[[controllers.schema-mapping.signature]]
==== Method Signature
Schema mapping handler methods can have any of the following method arguments:
@@ -1279,7 +1279,7 @@ 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 <<controllers-schema-mapping-argument>>.
See <<controllers.schema-mapping.argument>>.
| `@Argument Map<String, Object>`
| For access to the raw map of arguments, where `@Argument` does not have a
@@ -1288,26 +1288,26 @@ See <<controllers-schema-mapping-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 <<controllers-schema-mapping-argument-value>>.
See <<controllers.schema-mapping.argument-value>>.
| `@Arguments`
| For access to all field arguments bound to a higher-level, typed Object.
See <<controllers-schema-mapping-arguments>>.
See <<controllers.schema-mapping.arguments>>.
| `@Arguments Map<String, Object>`
| For access to the raw map of arguments.
| `@ProjectedPayload` Interface
| For access to field arguments through a project interface.
See <<controllers-schema-mapping-projectedpayload-argument>>.
See <<controllers.schema-mapping.projectedpayload.argument>>.
| "Source"
| For access to the source (i.e. parent/container) instance of the field.
See <<controllers-schema-mapping-source>>.
See <<controllers.schema-mapping.source>>.
| `DataLoader`
| For access to a `DataLoader` in the `DataLoaderRegistry`.
See <<controllers-schema-mapping-data-loader>>.
See <<controllers.schema-mapping.data-loader>>.
| `@ContextValue`
| For access to an attribute from the main `GraphQLContext` in `DataFetchingEnvironment`.
@@ -1339,12 +1339,12 @@ 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 <<execution-reactive-datafetcher>>.
any `DataFetcher` as described in <<execution.reactive-datafetcher>>.
- `java.util.concurrent.Callable` to have the value(s) produced asynchronously.
For this to work, `AnnotatedControllerConfigurer` must be configured with an `Executor`.
[[controllers-schema-mapping-argument]]
[[controllers.schema-mapping.argument]]
==== `@Argument`
In GraphQL Java, `DataFetchingEnvironment` provides access to a map of field-specific
@@ -1390,13 +1390,13 @@ You can use `@Argument` with a `Map<String, Object>` argument, to obtain the raw
all argument values. The name attribute on `@Argument` must not be set.
[[controllers-schema-mapping-argument-value]]
[[controllers.schema-mapping.argument-value]]
==== `ArgumentValue`
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 <<controllers-schema-mapping-argument>>
`null` or not changed at all accordingly. When using <<controllers.schema-mapping.argument>>
there is no way to make such a distinction, because you would get `null` or an empty
`Optional` in both cases.
@@ -1428,7 +1428,7 @@ method parameter, either initialized via a constructor argument or via a setter,
as a field of an object nested at any level below the top level object.
[[controllers-schema-mapping-arguments]]
[[controllers.schema-mapping.arguments]]
==== `@Arguments`
Use the `@Arguments` annotation, if you want to bind the full arguments map onto a single
@@ -1442,10 +1442,10 @@ You can use `@Arguments` with a `Map<String, Object>` argument, to obtain the ra
all argument values.
[[controllers-schema-mapping-projectedpayload-argument]]
[[controllers.schema-mapping.projectedpayload.argument]]
==== `@ProjectedPayload` Interface
As an alternative to using complete Objects with <<controllers-schema-mapping-argument>>,
As an alternative to using complete Objects with <<controllers.schema-mapping.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]
@@ -1493,7 +1493,7 @@ For example:
[[controllers-schema-mapping-source]]
[[controllers.schema-mapping.source]]
==== Source
In GraphQL Java, the `DataFetchingEnvironment` provides access to the source (i.e.
@@ -1518,16 +1518,16 @@ explicitly specify the type name in the `@SchemaMapping` annotation.
[TIP]
====
A <<controllers-batch-mapping>> handler method can batch load all authors for a query,
A <<controllers.batch-mapping>> handler method can batch load all authors for a query,
given a list of source/parent books objects.
====
[[controllers-schema-mapping-data-loader]]
[[controllers.schema-mapping.data-loader]]
==== `DataLoader`
When you register a batch loading function for an entity, as explained in
<<execution-batching>>, you can access the `DataLoader` for the entity by declaring a
<<execution.batching>>, 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"]
@@ -1558,10 +1558,10 @@ 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
<<controllers-batch-mapping,@BatchMapping>> method as described in the next section.
<<controllers.batch-mapping,@BatchMapping>> method as described in the next section.
[[controllers-schema-mapping-validation]]
[[controllers.schema-mapping.validation]]
==== Validation
When a `javax.validation.Validator` bean is found, `AnnotatedControllerConfigurer` enables support for
@@ -1599,15 +1599,15 @@ method invocation:
----
If an error occurs during validation, a `ConstraintViolationException` is raised.
You can use the <<execution-exceptions>> chain to decide how to present that to clients
You can use the <<execution.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 <<controllers-schema-mapping-argument>>,
<<controllers-schema-mapping-arguments>>, and
<<controllers-schema-mapping-projectedpayload-argument,@ProjectedPayload>>
Bean validation is useful for <<controllers.schema-mapping.argument>>,
<<controllers.schema-mapping.arguments>>, and
<<controllers.schema-mapping.projectedpayload.argument,@ProjectedPayload>>
method parameters, but applies more generally to any method parameter.
[WARNING]
@@ -1621,10 +1621,10 @@ for links to relevant issues and a suggested workaround.
[[controllers-batch-mapping]]
[[controllers.batch-mapping]]
=== `@BatchMapping`
<<execution-batching>> addresses the N+1 select problem through the use of an
<<execution.batching>> 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:
@@ -1679,7 +1679,7 @@ annotation attributes. The type name can also be inherited from a class level
`@SchemaMapping`.
[[controllers-batch-mapping-signature]]
[[controllers.batch-mapping.signature]]
==== Method Signature
Batch mapping methods support the following arguments:
@@ -1737,14 +1737,14 @@ Batch mapping methods can return:
[[security]]
== Security
The path to a <<server-transports, Web>> GraphQL endpoint can be secured with HTTP
The path to a <<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 <<execution-context>> that aims to make
the GraphQL response. This should work due to <<execution.context>> 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
@@ -1754,12 +1754,12 @@ The 1.0.x branch of this repository contains samples for
include::client.adoc[leveloffset=+1]
include::includes/client.adoc[leveloffset=+1]
include::testing.adoc[leveloffset=+1]
include::includes/testing.adoc[leveloffset=+1]