Starter for building GraphQL applications with Spring GraphQL
—
Spring Boot GraphQL Starter supports multiple transport protocols for GraphQL communication: HTTP, WebSocket, Server-Sent Events (SSE), and RSocket. Each transport is automatically configured and optimized for different use cases.
Standard HTTP POST requests for queries and mutations.
# HTTP endpoint configuration
spring.graphql.http.path=/graphql// HTTP client example
POST /graphql
Content-Type: application/json
Authorization: Bearer <token>
{
"query": "query GetBooks($limit: Int) { books(limit: $limit) { id title author } }",
"variables": { "limit": 10 },
"operationName": "GetBooks"
}GraphQL over WebSocket protocol for real-time subscriptions and bidirectional communication.
// WebSocket configuration
spring.graphql.websocket.path=/graphql-ws
spring.graphql.websocket.connection-init-timeout=30s
spring.graphql.websocket.keep-alive=15s@Bean
@ConditionalOnMissingBean
public GraphQlWebSocketHandler graphQlWebSocketHandler(
WebGraphQlHandler webGraphQlHandler,
GraphQlProperties properties,
HttpMessageConverters converters
) {
return new GraphQlWebSocketHandler(
webGraphQlHandler,
getJsonConverter(converters),
properties.getWebsocket().getConnectionInitTimeout(),
properties.getWebsocket().getKeepAlive()
);
}@Controller
public class BookSubscriptionController {
@SubscriptionMapping
public Flux<BookEvent> bookUpdates() {
return bookEventPublisher.getUpdates()
.map(this::toGraphQLEvent);
}
@SubscriptionMapping
public Flux<BookEvent> booksByAuthor(@Argument String authorId) {
return bookEventPublisher.getUpdatesByAuthor(authorId);
}
}HTTP-based streaming for GraphQL subscriptions using Server-Sent Events.
// SSE configuration
spring.graphql.http.sse.keep-alive=30s
spring.graphql.http.sse.timeout=60s@Bean
@ConditionalOnMissingBean
public GraphQlSseHandler graphQlSseHandler(
WebGraphQlHandler webGraphQlHandler,
GraphQlProperties properties
) {
return new GraphQlSseHandler(
webGraphQlHandler,
properties.getHttp().getSse().getTimeout(),
properties.getHttp().getSse().getKeepAlive()
);
}// JavaScript SSE client
const eventSource = new EventSource('/graphql?query=subscription{bookUpdates{id title}}');
eventSource.onmessage = function(event) {
const data = JSON.parse(event.data);
console.log('Book update:', data);
};GraphQL over RSocket for reactive, bidirectional, multiplexed communication.
// RSocket configuration
spring.graphql.rsocket.mapping=graphql
spring.rsocket.server.port=7000@AutoConfiguration(after = GraphQlAutoConfiguration.class)
@ConditionalOnClass({ GraphQL.class, RSocketRequester.class })
@ConditionalOnBean(GraphQlSource.class)
public class GraphQlRSocketAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public RSocketGraphQlHandler rSocketGraphQlHandler(WebGraphQlHandler handler) {
return new RSocketGraphQlHandler(handler, Arrays.asList(MediaType.APPLICATION_JSON));
}
}@Controller
public class RSocketGraphQlController {
@MessageMapping("graphql.query")
public Mono<Book> getBook(String query) {
return graphQlService.executeQuery(query)
.map(result -> (Book) result.getData());
}
@MessageMapping("graphql.subscription")
public Flux<BookEvent> bookStream(String subscription) {
return graphQlService.executeSubscription(subscription)
.map(result -> (BookEvent) result.getData());
}
}The starter automatically configures appropriate transports based on:
// Servlet-based applications
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
// -> HTTP, WebSocket, SSE
// Reactive applications
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
// -> Reactive HTTP, Reactive WebSocket, Reactive SSE
// RSocket applications
@ConditionalOnClass(RSocketRequester.class)
// -> RSocket transport// WebSocket connection limits
server.netty.max-connections=1000
// SSE timeout configuration
spring.graphql.http.sse.timeout=5m
spring.graphql.http.sse.keep-alive=30s
// RSocket connection pooling
spring.rsocket.server.transport=tcp
spring.rsocket.server.port=7000// HTTP request batching
POST /graphql
Content-Type: application/json
[
{"query": "query GetBooks { books { id title } }"},
{"query": "query GetAuthors { authors { id name } }"}
]@Component
public class TransportErrorHandler implements DataFetcherExceptionResolver {
@Override
public Mono<List<GraphQLError>> resolveException(DataFetcherExceptionResolverEnvironment env) {
Throwable exception = env.getException();
if (exception instanceof WebSocketConnectionException) {
return Mono.just(List.of(
GraphqlErrorBuilder.newError(env)
.message("WebSocket connection failed")
.extensions(Map.of("transport", "websocket"))
.build()
));
}
return Mono.empty();
}
}// HTTP security
spring.security.require-ssl=true
// WebSocket security
spring.graphql.websocket.allowed-origins=https://example.com
// RSocket security
spring.rsocket.server.ssl.enabled=true
spring.rsocket.server.ssl.key-store=classpath:keystore.p12Install with Tessl CLI
npx tessl i tessl/maven-org-springframework-boot--spring-boot-starter-graphql