0
# Core Infrastructure
1
2
The Spring Boot GraphQL Starter provides fundamental GraphQL infrastructure through auto-configured Spring beans. These components form the foundation for GraphQL schema loading, execution, and request processing.
3
4
## Auto-Configured Core Beans
5
6
### GraphQlSource
7
8
The central component that holds the GraphQL schema and execution configuration.
9
10
```java { .api }
11
@Bean
12
@ConditionalOnMissingBean
13
public GraphQlSource graphQlSource(
14
ResourcePatternResolver resourcePatternResolver,
15
GraphQlProperties properties,
16
ObjectProvider<DataFetcherExceptionResolver> exceptionResolvers,
17
ObjectProvider<SubscriptionExceptionResolver> subscriptionExceptionResolvers,
18
ObjectProvider<Instrumentation> instrumentations,
19
ObjectProvider<RuntimeWiringConfigurer> wiringConfigurers,
20
ObjectProvider<GraphQlSourceBuilderCustomizer> sourceCustomizers
21
) {
22
// Auto-configured with schema loading and customization
23
}
24
```
25
26
### ExecutionGraphQlService
27
28
Service responsible for executing GraphQL requests against the schema.
29
30
```java { .api }
31
@Bean
32
@ConditionalOnMissingBean
33
public ExecutionGraphQlService executionGraphQlService(
34
GraphQlSource graphQlSource,
35
BatchLoaderRegistry batchLoaderRegistry
36
) {
37
DefaultExecutionGraphQlService service = new DefaultExecutionGraphQlService(graphQlSource);
38
service.addDataLoaderRegistrar(batchLoaderRegistry);
39
return service;
40
}
41
```
42
43
### BatchLoaderRegistry
44
45
Registry for DataLoader instances to solve the N+1 query problem.
46
47
```java { .api }
48
@Bean
49
@ConditionalOnMissingBean
50
public BatchLoaderRegistry batchLoaderRegistry() {
51
return new DefaultBatchLoaderRegistry();
52
}
53
```
54
55
### AnnotatedControllerConfigurer
56
57
Configures support for `@Controller` classes with GraphQL mapping annotations.
58
59
```java { .api }
60
@Bean
61
@ConditionalOnMissingBean
62
public AnnotatedControllerConfigurer annotatedControllerConfigurer(
63
@Qualifier(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME) ObjectProvider<Executor> executorProvider,
64
ObjectProvider<HandlerMethodArgumentResolver> argumentResolvers
65
) {
66
AnnotatedControllerConfigurer configurer = new AnnotatedControllerConfigurer();
67
// Configured with executors and custom argument resolvers
68
return configurer;
69
}
70
```
71
72
## Schema Loading
73
74
### Default Schema Discovery
75
76
The starter automatically discovers GraphQL schema files from default locations:
77
78
```java { .api }
79
// Default schema configuration
80
public class Schema {
81
private String[] locations = {"classpath:graphql/**/"};
82
private String[] fileExtensions = {".graphqls", ".gqls"};
83
private Resource[] additionalFiles = {};
84
}
85
```
86
87
Schema files are loaded recursively from:
88
- `src/main/resources/graphql/` (all subdirectories)
89
- Files with extensions: `.graphqls`, `.gqls`
90
- Additional files can be specified via configuration
91
92
### Schema Inspection
93
94
Built-in schema validation and inspection capabilities:
95
96
```java { .api }
97
public class Inspection {
98
private boolean enabled = true; // Schema-to-application mapping validation
99
}
100
101
public class Introspection {
102
private boolean enabled = true; // Runtime schema introspection
103
}
104
```
105
106
Usage example:
107
```java
108
// Enable detailed schema inspection logging
109
spring.graphql.schema.inspection.enabled=true
110
111
// Disable introspection in production
112
spring.graphql.schema.introspection.enabled=false
113
```
114
115
## Exception Handling
116
117
### DataFetcherExceptionResolver
118
119
Handle exceptions during GraphQL field resolution:
120
121
```java { .api }
122
public interface DataFetcherExceptionResolver {
123
Mono<List<GraphQLError>> resolveException(DataFetcherExceptionResolverEnvironment environment);
124
}
125
```
126
127
Implementation example:
128
```java
129
@Component
130
public class CustomExceptionResolver implements DataFetcherExceptionResolver {
131
132
@Override
133
public Mono<List<GraphQLError>> resolveException(DataFetcherExceptionResolverEnvironment env) {
134
Throwable exception = env.getException();
135
136
if (exception instanceof ValidationException) {
137
GraphQLError error = GraphqlErrorBuilder.newError()
138
.message("Validation failed: " + exception.getMessage())
139
.location(env.getField().getSourceLocation())
140
.errorType(ErrorType.ValidationError)
141
.build();
142
return Mono.just(List.of(error));
143
}
144
145
return Mono.empty(); // Let other resolvers handle
146
}
147
}
148
```
149
150
### SubscriptionExceptionResolver
151
152
Handle exceptions during GraphQL subscription streams:
153
154
```java { .api }
155
public interface SubscriptionExceptionResolver {
156
Mono<List<GraphQLError>> resolveException(SubscriptionExceptionResolverEnvironment environment);
157
}
158
```
159
160
## Instrumentation
161
162
### GraphQL Instrumentation
163
164
Add cross-cutting concerns to GraphQL execution:
165
166
```java { .api }
167
public interface Instrumentation {
168
InstrumentationState createState(InstrumentationCreateStateParameters parameters);
169
InstrumentationContext<ExecutionResult> beginExecution(InstrumentationExecutionParameters parameters);
170
// Additional instrumentation hooks...
171
}
172
```
173
174
Usage example:
175
```java
176
@Component
177
public class TimingInstrumentation implements Instrumentation {
178
179
@Override
180
public InstrumentationContext<ExecutionResult> beginExecution(InstrumentationExecutionParameters parameters) {
181
long startTime = System.currentTimeMillis();
182
183
return new SimpleInstrumentationContext<ExecutionResult>() {
184
@Override
185
public void onCompleted(ExecutionResult result, Throwable t) {
186
long duration = System.currentTimeMillis() - startTime;
187
log.info("GraphQL execution took {}ms", duration);
188
}
189
};
190
}
191
}
192
```
193
194
## Runtime Wiring Customization
195
196
### RuntimeWiringConfigurer
197
198
Customize the GraphQL runtime wiring to add custom DataFetchers, type resolvers, and scalar types:
199
200
```java { .api }
201
public interface RuntimeWiringConfigurer {
202
void configure(RuntimeWiring.Builder builder);
203
}
204
```
205
206
Usage example:
207
```java
208
@Component
209
public class CustomWiringConfigurer implements RuntimeWiringConfigurer {
210
211
@Override
212
public void configure(RuntimeWiring.Builder builder) {
213
builder
214
.scalar(ExtendedScalars.DateTime)
215
.type("Query", typeWiring -> typeWiring
216
.dataFetcher("customField", customDataFetcher))
217
.type("Book", typeWiring -> typeWiring
218
.dataFetcher("author", authorDataFetcher));
219
}
220
}
221
```
222
223
## Source Builder Customization
224
225
### GraphQlSourceBuilderCustomizer
226
227
Customize the GraphQL source building process:
228
229
```java { .api }
230
public interface GraphQlSourceBuilderCustomizer {
231
void customize(GraphQlSource.SchemaResourceBuilder builder);
232
}
233
```
234
235
Usage example:
236
```java
237
@Component
238
public class SchemaCustomizer implements GraphQlSourceBuilderCustomizer {
239
240
@Override
241
public void customize(GraphQlSource.SchemaResourceBuilder builder) {
242
builder
243
.configureTypeDefinitions(registry -> {
244
// Modify type definitions
245
})
246
.configureRuntimeWiring(wiringBuilder -> {
247
// Configure runtime wiring
248
});
249
}
250
}
251
```
252
253
## Conditional Configuration
254
255
The core infrastructure is conditionally configured based on:
256
257
```java { .api }
258
@ConditionalOnClass({GraphQL.class, GraphQlSource.class})
259
@ConditionalOnGraphQlSchema // Custom condition checking for schema files
260
```
261
262
The `@ConditionalOnGraphQlSchema` annotation ensures GraphQL infrastructure is only configured when:
263
- GraphQL schema files are present in default locations, OR
264
- Additional schema files are configured, OR
265
- Custom `GraphQlSource` bean is provided
266
267
## Integration Points
268
269
### Spring Data Integration
270
271
Automatic cursor strategy configuration for pagination:
272
273
```java { .api }
274
@ConditionalOnClass(ScrollPosition.class)
275
@Configuration(proxyBeanMethods = false)
276
static class GraphQlDataAutoConfiguration {
277
278
@Bean
279
@ConditionalOnMissingBean
280
EncodingCursorStrategy<ScrollPosition> cursorStrategy() {
281
return CursorStrategy.withEncoder(
282
new ScrollPositionCursorStrategy(),
283
CursorEncoder.base64()
284
);
285
}
286
}
287
```
288
289
### Runtime Hints for Native Compilation
290
291
Native compilation support through runtime hints:
292
293
```java { .api }
294
static class GraphQlResourcesRuntimeHints implements RuntimeHintsRegistrar {
295
@Override
296
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
297
hints.resources()
298
.registerPattern("graphql/*.graphqls")
299
.registerPattern("graphql/*.gqls");
300
}
301
}
302
```