Polishing docs on server interception

See gh-487
This commit is contained in:
rstoyanchev
2022-09-13 11:20:02 +01:00
parent 2f598ed00e
commit 15b049248f

View File

@@ -155,30 +155,40 @@ public class GraphQlRSocketController {
[[server-interception]]
=== Interception
Transport handlers for <<server-http>> and <<server-websocket>> delegate to a
`WebGraphQlInterceptor` chain with an `ExecutionGraphQlService` at the end which calls
the GraphQL Java engine. Use this to access HTTP request details and customize the
`ExecutionInput` for GraphQL Java.
Server transports allow intercepting requests before and after the GraphQL Java engine is
called to process a request.
For example, to extract HTTP request values and pass them to data fetchers:
[[server-interception-web]]
==== `WebGraphQlInterceptor`
<<server-http>> and <<server-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:
- Check HTTP request details
- Customize the `graphql.ExecutionInput`
- Add HTTP response headers
- Customize the `graphql.ExecutionResult`
For example, an interceptor can pass an HTTP request header to a `DataFetcher`:
[source,java,indent=0,subs="verbatim,quotes"]
----
class HeaderInterceptor implements WebGraphQlInterceptor {
class HeaderInterceptor implements WebGraphQlInterceptor { <1>
@Override
public Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, Chain chain) {
List<String> values = request.getHeaders().get("headerName");
String value = request.getHeaders().getFirst("myHeader");
request.configureExecutionInput((executionInput, builder) ->
builder.graphQLContext(Collections.singletonMap("headerName", values)).build());
builder.graphQLContext(Collections.singletonMap("myHeader", value)).build());
return chain.next(request);
}
}
// Subsequent access from a controller
@Controller
class MyController {
class MyController { <2>
@QueryMapping
Person person(@ContextValue String myHeader) {
@@ -186,8 +196,10 @@ class MyController {
}
}
----
<1> Interceptor adds HTTP request header value into GraphQLContext
<2> Data controller method accesses the value
Or reversely, add values to the `GraphQLContext` and use them to update the HTTP response:
Reversely, an interceptor can access values added to the `GraphQLContext` by a controller:
[source,java,indent=0,subs="verbatim,quotes"]
----
@@ -195,7 +207,7 @@ Or reversely, add values to the `GraphQLContext` and use them to update the HTTP
class MyController {
@QueryMapping
Person person(GraphQLContext context) {
Person person(GraphQLContext context) { <1>
context.put("cookieName", "123");
}
}
@@ -205,7 +217,7 @@ class MyController {
class HeaderInterceptor implements WebGraphQlInterceptor {
@Override
public Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, Chain chain) {
public Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, Chain chain) { <2>
return chain.next(request).doOnNext(response -> {
String value = response.getExecutionInput().getGraphQLContext().get("cookieName");
ResponseCookie cookie = ResponseCookie.from("cookieName", value).build();
@@ -214,13 +226,20 @@ class HeaderInterceptor implements WebGraphQlInterceptor {
}
}
----
<1> Controller adds value to the `GraphQLContext`
<2> Interceptor uses the value to add an HTTP response header
The `WebGraphQlInterceptor` chain can be updated through the `WebGraphQlHandler` builder,
and the Boot starter uses this, see Boot's section on
You can add a `WebGraphQlInterceptor` through `WebGraphQlHandler` builder. The Boot starter
supports this, see
{spring-boot-ref-docs}/web.html#web.graphql.transports.http-websocket[Web Endpoints].
The <<server-rsocket>> transport handler delegates to a similar `GraphQlInterceptor`
chain that you can use to intercept GraphQL over RSocket requests.
[[server-interception-rsocket]]
==== `RSocketQlInterceptor`
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`.