Update documentation for RSocket

See gh-339
This commit is contained in:
rstoyanchev
2022-03-28 08:04:31 +00:00
parent 5b93c1fce7
commit 681a0dcf4d
2 changed files with 109 additions and 52 deletions

View File

@@ -6,8 +6,8 @@ include::attributes.adoc[]
[[client]]
= Client
Spring for GraphQL includes client support for executing GraphQL requests over HTTP or
over WebSocket.
Spring for GraphQL includes client support for executing GraphQL requests over HTTP,
WebSocket, and RSocket.
@@ -108,6 +108,26 @@ on an existing `WebSocketGraphQlClient` to create another with different configu
[[client-rsocketgraphqlclient]]
=== RSocket
`RSocketGraphQlClient` uses
{spring-framework-ref-docs}/web-reactive.html#rsocket-requester[RSocketRequester]
to execute GraphQL requests over RSocket requests.
[source,java,indent=0,subs="verbatim,quotes"]
----
RSocketGraphQlClient graphQlClient =
RSocketGraphQlClient.builder()
.websocket(URI.create("http://localhost:8080/graphql"))
.build();
----
Once created, `RSocketGraphQlClient` exposes the same transport agnostic workflow for
request execution as any `GrahQlClient`.
[[client-websocketgraphqlclient-connection]]
==== Connection

View File

@@ -35,18 +35,18 @@ Spring for GraphQL requires the following as a baseline:
[[web-transports]]
== Web Transports
[[server-transports]]
== Server Transports
Spring for GraphQL supports GraphQL requests over HTTP and over WebSocket.
Spring for GraphQL supports server handling of GraphQL requests over HTTP, WebSocket, and
RSocket.
[[web-http]]
[[server-http]]
=== HTTP
`GraphQlHttpHandler` handles GraphQL over HTTP requests and delegates to the
<<web-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.
@@ -70,7 +70,7 @@ The Spring for GraphQL repository contains a Spring MVC
[[web-websocket]]
[[server-websocket]]
=== WebSocket
`GraphQlWebSocketHandler` handles GraphQL over WebSocket requests based on the
@@ -78,7 +78,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 <<web-interception>> chain for further
The handler delegates every request to the <<server-interception>> chain for further
request execution.
[TIP]
@@ -113,17 +113,52 @@ The Spring for GraphQL repository contains a WebFlux
[[web-interception]]
=== Web Interception
[[server-rsocket]]
=== RSocket
<<web-http>> and <<web-websocket>> transport handlers delegate to a common Web
interception chain for request execution. The chain consists of a sequence of
`WebGraphQlInterceptor` components, followed by a `ExecutionGraphQlService` that
invokes GraphQL Java.
`GraphQlRSocketHandler` handles GraphQL over RSocket requests. Queries and mutations are
expected and handled as an RSocket `request-response` interaction while subscriptions are
handled as `request-stream`.
`WebGraphQlInterceptor` is as a common contract to use in both Spring MVC and
WebFlux applications. Use it to intercept requests, inspect HTTP request headers, or to
register a transformation of the `graphql.ExecutionInput`:
`GraphQlRSocketHandler` can be used a delegate from an `@Controller` that is mapped to
the route for GraphQL requests. For example:
[source,java,indent=0,subs="verbatim,quotes"]
----
@Controller
public class GraphQlRSocketController {
private final GraphQlRSocketHandler handler;
GraphQlRSocketController(GraphQlRSocketHandler handler) {
this.handler = handler;
}
@MessageMapping("graphql")
public Mono<Map<String, Object>> handle(Map<String, Object> payload) {
return this.handler.handle(payload);
}
@MessageMapping("graphql")
public Flux<Map<String, Object>> handleSubscription(Map<String, Object> payload) {
return this.handler.handleSubscription(payload);
}
}
----
[[server-interception]]
=== Server Interception
GraphQL <<server-http>> and <<server-websocket>> handlers for Spring MVC and WebFlux
delegate to a common `WebGraphQlInterceptor` chain followed by an `ExecutionGraphQlService`
that invokes the GraphQL Java engine.
You can write an interceptor to check requests details or transform the
`graphql.ExecutionInput` for GraphQL Java:
[source,java,indent=0,subs="verbatim,quotes"]
----
@@ -140,8 +175,8 @@ class MyInterceptor implements WebGraphQlInterceptor {
}
----
Use `WebGraphQlInterceptor` also to intercept responses, add HTTP response headers,
or transform the `graphql.ExecutionResult`:
Interceptors can customize HTTP response headers, or inspect and/or transform the
`graphql.ExecutionResult` from GraphQL Java:
[source,java,indent=0,subs="verbatim,quotes"]
----
@@ -159,19 +194,22 @@ class MyInterceptor implements WebGraphQlInterceptor {
}
----
`WebGraphQlHandler` provides a builder to initialize the Web interception chain. After
you build the chain, you can use the resulting `WebGraphQlHandler` to initialize the HTTP
or WebSocket transport handlers. The Boot starter configures all this, see the
{spring-boot-ref-docs}/web.html#web.graphql.web-endpoints[Web Endpoints] section for
details, or check `GraphQlWebMvcAutoConfiguration` or `GraphQlWebFluxAutoConfiguration`
it contains, for the actual config.
`WebGraphQlHandler` has a builder to create the `WebGraphInterceptor` chain. The Boot
starter uses this, see Boot's section on
{spring-boot-ref-docs}/web.html#web.graphql.web-endpoints[Web Endpoints].
The <<server-rsocket>> handler delegates to a similar chain except
the interceptor type is `GraphQlInterceptor`. To use, create `GraphQlRSocketHandler` with
the list of interceptors to apply to requests.
[[execution]]
== Request Execution
`ExecutionGraphQlService` is the main Spring abstraction to call GraphQL Java to execute
requests. Underlying transports, such as the <<web-transports>>, delegate to
requests. Underlying transports, such as the <<server-transports>>, delegate to
`ExecutionGraphQlService` to handle requests.
The main implementation, `DefaultExecutionGraphQlService`, is configured with a
@@ -212,10 +250,9 @@ class GraphQlConfig {
@Bean
public GraphQlSourceBuilderCustomizer sourceBuilderCustomizer() {
return (builder) -> {
builder.configureGraphQl(graphQlBuilder ->
graphQlBuilder.executionIdProvider(new CustomExecutionIdProvider()));
};
return (builder) ->
builder.configureGraphQl(graphQlBuilder ->
graphQlBuilder.executionIdProvider(new CustomExecutionIdProvider()));
}
}
----
@@ -380,10 +417,10 @@ such beans, so you might have something like:
@Configuration
public class GraphQlConfig {
@Bean
public RuntimeWiringConfigurer runtimeWiringConfigurer() {
return builder -> builder.directiveWiring(new MySchemaDirectiveWiring());
}
@Bean
public RuntimeWiringConfigurer runtimeWiringConfigurer() {
return builder -> builder.directiveWiring(new MySchemaDirectiveWiring());
}
}
----
@@ -413,7 +450,7 @@ transport layer, such as from a WebFlux request handling, see
=== Context Propagation
Spring for GraphQL provides support to transparently propagate context from the
<<web-transports>>, through GraphQL Java, and to `DataFetcher` and other components it
<<server-transports>>, 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.
@@ -423,7 +460,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
<<web-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
@@ -457,7 +494,7 @@ public class RequestAttributesAccessor implements ThreadLocalAccessor {
}
----
A `ThreadLocalAccessor` can be registered in the <<web-interception,WebGraphHandler>>
A `ThreadLocalAccessor` can be registered in the <<server-interception,WebGraphHandler>>
builder. The Boot starter detects beans of this type and automatically registers them for
Spring MVC application, see the
{spring-boot-ref-docs}/web.html#web.graphql.web-endpoints[Web Endpoints] section.
@@ -468,7 +505,7 @@ Spring MVC application, see the
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 <<web-interception, WebGraphQlInterceptor>> components.
added by <<server-interception, WebGraphQlInterceptor>> components.
@@ -546,11 +583,11 @@ public class MyConfig {
public MyConfig(BatchLoaderRegistry registry) {
registry.forTypePair(Long.class, Author.class).registerMappedBatchLoader((authorIds, env) -> {
// return Mono<Map<Long, Author>
});
// return Mono<Map<Long, Author>
});
// more registrations ...
}
// more registrations ...
}
}
----
@@ -679,12 +716,12 @@ dependencies {
//...
annotationProcessor "com.querydsl:querydsl-apt:$querydslVersion:jpa",
'org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.2.Final',
'javax.annotation:javax.annotation-api:1.3.2'
'org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.2.Final',
'javax.annotation:javax.annotation-api:1.3.2'
}
compileJava {
options.annotationProcessorPath = configurations.annotationProcessor
options.annotationProcessorPath = configurations.annotationProcessor
}
----
[source,xml,indent=0,subs="verbatim,quotes,attributes",role="secondary"]
@@ -1238,12 +1275,12 @@ Bean Validation lets you declare constraints on types, as the following example
----
public class BookInput {
@NotNull
private String title;
@NotNull
private String title;
@NotNull
@Size(max=13)
private String isbn;
@Size(max=13)
private String isbn;
}
----
@@ -1502,7 +1539,7 @@ Batch mapping methods can return:
[[security]]
== Security
The path to a <<web-transports, Web>> GraphQL endpoint can be secured with HTTP
The path to a <<server-transports, 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.