@@ -5,85 +5,195 @@ Brian Clozel; Andreas Marek; Rossen Stoyanchev
55:tabsize: 4
66
77
8-
8+ [[web]]
99== Web Transports
1010
11- TODO...
11+ Spring GraphQL supports GraphQL requests over HTTP and over WebSocket. It comes with a choice
12+ of handlers for Spring MVC and Spring WebFlux applications.
13+
1214
1315
16+ [[web-http]]
1417=== HTTP
1518
16- TODO...
19+ `GraphQlHttpHandler` classes, in their respective WebMvc and WebFlux sub-packages, provide
20+ handling of GraphQL over HTTP requests and both delegate to a common <<web-interceptor>>
21+ chain for actual handling and query execution.
22+
23+ The HTTP handlers for WebMvc and WebFlux have equivalent functionality. Both perform
24+ asynchronous execution of GraphQL queries, while the WebFlux handler also uses non-blocking
25+ I/O to write to the HTTP response.
1726
27+ Requests should have the HTTP POST method with the query in the request body as defined in the
28+ https://github.com/graphql/graphql-over-http/blob/main/spec/GraphQLOverHTTP.md[GraphQL over HTTP]
29+ spec proposal.
1830
31+ The handlers can be exposed as endpoints by declaring a `RouterFunction` bean and using
32+ the `RouterFunctions`, functional endpoint DSL for WebMvc or WebFlux respectively to
33+ create the mappings. The Boot starter does this by default, see <<boot-graphql-web>> for
34+ details or look in the `GraphQlWebMvcAutoConfiguration` or
35+ `GraphQlWebFluxAutoConfiguration` classes for example config.
36+
37+
38+
39+ [[web-websocket]]
1940=== WebSocket
2041
21- TODO...
42+ `GraphQlWebSocketHandler` classes, in their respective WebMvc and WebFlux sub-packages,
43+ support GraphQL over WebSocket requests based on the
44+ https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md[protocol] defined in the
45+ `graphql-ws` library that also lists a number of
46+ https://github.com/enisdenjo/graphql-ws#recipes[recipes] for use with various clients.
2247
48+ [TIP]
49+ .GraphQL Over WebSocket Protocols
50+ ====
51+ There are two such protocols, one in the
52+ https://github.com/apollographql/subscriptions-transport-ws[subscriptions-transport-ws]
53+ library and another in the
54+ https://github.com/enisdenjo/graphql-ws[graphql-ws] library. The former is not active and
55+ succeeded by the latter. Read this
56+ https://the-guild.dev/blog/graphql-over-websockets[blog post] for the history.
57+ ====
58+
59+ The WebSocket handlers for WebMvc and WebFlux have equivalent functionality. Both perform
60+ asynchronous execution of GraphQL queries, but the WebFlux handler also uses non-blocking
61+ I/O and back pressure to stream messages to the WebSocket connection.
62+
63+ GraphQL over WebSocket protocol supports the execution both queries and streaming
64+ subscriptions and the <<web-interceptor>> can be used to intercept each query or
65+ subscription request.
66+
67+ The handlers can be exposed as endpoints by declaring `SimpleUrlHandlerMapping` beans for
68+ WebMvc or WebFlux respectively. The Boot starter provides options to enable and conifgure
69+ all this, see<<boot-graphql-web>> for details or look in the `GraphQlWebMvcAutoConfiguration`
70+ or `GraphQlWebFluxAutoConfiguration` classes for example configuration.
71+
72+
73+
74+ [[web-interceptor]]
2375=== `WebInterceptor` API
2476
25- TODO...
77+ Web transport handlers for <<web-http>> and for <<web-websocket>> delegate to a
78+ `WebGraphQlHandler` that represents a chain of `WebInterceptor` components, followed by a
79+ `GraphQlSource` that actually invokes the GraphQL Java engine.
80+
81+ A `WebInterceptor` can be used to examine HTTP request input and potentially change the
82+ `ExecutionInput` passed to `graphql.GraphQL`:
83+
84+ [source,java,indent=0,subs="verbatim,quotes"]
85+ ----
86+ class MyInterceptor implements WebInterceptor {
87+
88+ @Override
89+ public Mono<WebOutput> intercept(WebInput webInput, WebGraphQlHandler next) {
90+ webInput.configureExecutionInput((executionInput, builder) -> {
91+ Map<String, Object> map = ... ;
92+ return builder.extensions(map).build();
93+ });
94+ return next.handle(webInput);
95+ }
96+ }
97+ ----
98+
99+ A `WebInterceptor` can be used to inspect and potentially modify the `ExecutionResult`
100+ or add an HTTP response header:
101+
102+ [source,java,indent=0,subs="verbatim,quotes"]
103+ ----
104+ class MyInterceptor implements WebInterceptor {
105+
106+ @Override
107+ public Mono<WebOutput> intercept(WebInput webInput, WebGraphQlHandler next) {
108+ return next.handle(webInput)
109+ .map(webOutput -> {
110+ Object data = webOutput.getData();
111+ Object updatedData = ... ;
112+ return webOutput.transform(builder -> builder.data(updatedData));
113+ });
114+ }
115+ }
116+ ----
117+
118+ `WebGraphQlHandler` provides a builder to assemble the processing chain given a
119+ a set of `WebInterceptor` components and a `GraphQlSource`. This handler is then passed
120+ to one of the web transport handlers. The Boot starter does all this by detecting beans
121+ of type `WebInterceptor` and using them to build the processing chain, see
122+ <<boot-graphql-web>> for details, or look in the `GraphQlWebMvcAutoConfiguration` or
123+ `GraphQlWebFluxAutoConfiguration` classes for example configuration.
124+
26125
27126
127+ [[execution]]
28128== Query Execution
29129
30130TODO...
31131
32132
133+ [[execution-configuring]]
33134=== Configuring the GraphQL Engine
34135
35136TODO...
36137
37138
139+ [[execution-datafetcher]]
38140=== `DataFetcher` Support
39141
40142TODO...
41143
42144
145+ [[execution-context]]
43146=== Context Management
44147
45148TODO...
46149
47150
151+ [[execution-exceptions]]
48152=== Exception Resolution
49153
50154TODO...
51155
52156
53157
54158
159+ [[data]]
55160== Data Integrations
56161
57162TODO...
58163
59164
165+ [[data-querydsl]]
60166=== QueryDsl
61167
62168TODO...
63169
64170
65171
66172
173+ [[data-security]]
67174== Security
68175
69176TODO...
70177
71178
72179
73180
181+ [[testing]]
74182== Testing
75183
76184TODO...
77185
78186
79187
80188
189+ [[boot-graphql]]
81190== Boot config
82191
83192This project is tested against Spring Boot 2.4+.
84193
85194
86195
196+ [[boot-graphql-project]]
87197=== Project Setup
88198
89199To create a project, go to https://start.spring.io and select starter(s) for the
@@ -170,6 +280,7 @@ released in Spring Boot 2.7 building on Spring GraphQL 1.0.
170280
171281
172282
283+ [[boot-graphql-schema]]
173284=== GraphQL Schema
174285
175286By default, GraphQL schema files are expected to be in `src/main/resources/graphql` and have
@@ -181,15 +292,16 @@ schema locations to check as follows:
181292spring.graphql.schema.locations=classpath:graphql/
182293----
183294
184- The GraphQL schema can be viewed over HTTP at "/graphql/schema", relative to the main graphql endpoint path.
185- It is disabled by default:
295+ The GraphQL schema can be viewed over HTTP at "/graphql/schema". This is not enabled by
296+ default:
186297
187298[source,properties,indent=0,subs="verbatim,quotes"]
188299----
189300spring.graphql.schema.printer.enabled=false
190301----
191302
192303
304+ [[boot-graphql-datafetcher]]
193305=== `DataFetcher` Registration
194306
195307You can declare `RuntimeWiringCustomizer` beans in your Spring config and use those to
@@ -215,17 +327,18 @@ public class PersonDataWiring implements RuntimeWiringCustomizer {
215327----
216328
217329
330+ [[boot-graphql-web]]
218331=== Web Transports
219332
220- The GraphQL HTTP endpoint path is "/graphql" by default but can be customized:
333+ The GraphQL HTTP endpoint is at HTTP POST "/graphql" by default. The path can be customized:
221334
222335[source,properties,indent=0,subs="verbatim,quotes"]
223336----
224337spring.graphql.path=/graphql
225338----
226339
227- The GraphQL WebSocket endpoint path is "/graphql" by default. The below configuration
228- properties apply to the WebSocket endpoint :
340+ The GraphQL WebSocket endpoint supports WebSocket handshakes at "/graphql" by default.
341+ The below shows the properties that apply for WebSocket handling :
229342
230343[source,properties,indent=0,subs="verbatim,quotes"]
231344----
@@ -244,6 +357,7 @@ The GraphQL WebSocket endpoint is not enabled by default. To enable it:
244357intercept for both GraphQL requests over HTTP and over WebSocket.
245358
246359
360+ [[boot-graphql-graphiql]]
247361=== GraphiQL Page
248362
249363The Spring Boot starter includes a https://github.com/graphql/graphiql[GraphiQL] page
@@ -258,6 +372,7 @@ spring.graphql.graphiql.path=/graphiql
258372
259373
260374
375+ [[boot-graphql-metrics]]
261376=== Metrics
262377
263378When the starter `spring-boot-starter-actuator` is present on the classpath, metrics for
@@ -277,6 +392,7 @@ management.endpoints.web.exposure.include=health,metrics,info
277392----
278393
279394
395+ [[boot-graphql-metrics-request-timer]]
280396==== GraphQL Request Timer
281397
282398A Request metric timer is available at `/actuator/metrics/graphql.request`.
@@ -291,6 +407,7 @@ A Request metric timer is available at `/actuator/metrics/graphql.request`.
291407|===
292408
293409
410+ [[boot-graphql-metrics-datafetcher-timer]]
294411==== GraphQL `DataFetcher` Timer
295412
296413A `DataFetcher` metric timer is available at `/actuator/metrics/graphql.datafetcher`.
@@ -309,6 +426,7 @@ A `DataFetcher` metric timer is available at `/actuator/metrics/graphql.datafetc
309426|===
310427
311428
429+ [[boot-graphql-metrics-error-counter]]
312430==== GraphQL Error Counter
313431
314432A GraphQL error metric counter is available at `/actuator/metrics/graphql.error`.
@@ -328,6 +446,7 @@ A GraphQL error metric counter is available at `/actuator/metrics/graphql.error`
328446
329447
330448
449+ [[boot-graphql-testing]]
331450=== Testing
332451
333452When the starter `spring-boot-starter-test` is present on the classpath, a `WebGraphQlTester`
@@ -414,6 +533,7 @@ chain and then calls GraphQL Java which returns a Reactive Streams `Publisher`.
414533
415534
416535
536+ [[samples]]
417537== Samples
418538
419539This Spring GraphQL repository contains
0 commit comments