Appearance
Spring Integration GraphQL 支持教程
专为初学者设计,通过实用示例逐步掌握 GraphQL 在 Spring Integration 中的应用
一、GraphQL 集成概述
Spring Integration 提供通道适配器实现与 GraphQL 协议的交互,基于 Spring for GraphQL 实现。核心功能:
- ✅ 出站网关:执行 GraphQL 查询/变更/订阅操作
- ✅ 响应式支持:返回
Mono<ExecutionGraphQlResponse>
- ✅ 灵活配置:支持静态或 SpEL 动态表达式
典型应用场景
- 微服务间 GraphQL 通信
- 非 HTTP 协议接入 GraphQL(如消息队列)
- 订阅实时数据流
二、环境配置
1. 添加依赖
kotlin
// build.gradle.kts
dependencies {
implementation("org.springframework.integration:spring-integration-graphql:6.5.1")
}
xml
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-graphql</artifactId>
<version>6.5.1</version>
</dependency>
2. 基础配置
kotlin
@Configuration
class GraphQLConfig {
// 创建 GraphQL 数据源
@Bean
fun graphQlSource(): GraphQlSource = GraphQlSource.builder()
.schemaResources(ClassPathResource("schema.graphqls"))
.configureRuntimeWiring(annotatedConfigurer())
.build()
// 注册数据获取器
@Bean
fun annotatedConfigurer() = AnnotatedControllerConfigurer()
// 构建 GraphQL 服务
@Bean
fun graphQlService(graphQlSource: GraphQlSource): ExecutionGraphQlService =
DefaultExecutionGraphQlService(graphQlSource)
}
三、GraphQL 出站网关
GraphQlMessageHandler
是核心组件,用于执行 GraphQL 操作并返回响应。
1. 网关配置选项
参数 | 说明 |
---|---|
operation | GraphQL 操作语句(静态或 SpEL) |
operationName | 操作名称(可选) |
variablesExpression | 参数变量(Map 或 JSON 字符串) |
executionId | 执行 ID(默认使用消息头的 id ) |
2. 创建网关示例
kotlin
@Bean
fun graphQlGateway(graphQlService: ExecutionGraphQlService): GraphQlMessageHandler =
GraphQl.gateway(graphQlService)
.operation("""
query HeroData($episode: Episode!) {
hero(episode: $episode) {
name
friends { name }
}
}
""".trimIndent())
.variablesExpression("{episode:'JEDI'}") // pEL 动态传参
.get()
四、集成流实战
1. 查询/变更操作流
kotlin
@Bean
fun graphqlFlow(handler: GraphQlMessageHandler): IntegrationFlow =
IntegrationFlow.from(MessageChannels.flux("inputChannel"))
.handle(handler)
.channel { c -> c.flux("resultChannel") }
.get()
2. 订阅操作特殊处理
订阅注意事项
订阅操作返回 SubscriptionPublisher
,需手动处理数据流:
kotlin
@ServiceActivator(inputChannel = "resultChannel")
fun handleSubscription(response: ExecutionGraphQlResponse): Flux<String> {
return response.getData<SubscriptionPublisher>()
.flatMap { data ->
// 转换订阅数据流
Flux.from(data).map { it.toString() }
}
}
五、动态参数进阶技巧
1. SpEL 动态表达式
kotlin
GraphQl.gateway(graphQlService)
.operationExpression("headers['operation']") // 从消息头获取操作
.variablesExpression("payload.variables") // 从消息体获取变量
2. 完整请求对象处理
若消息负载是 ExecutionGraphQlRequest
对象,网关直接执行:
kotlin
// 构建自定义请求
val request = ExecutionGraphQlRequest.Builder()
.query("query { user(id: 1) { name } }")
.build()
// 发送请求
val message = MessageBuilder.withPayload(request).build()
inputChannel.send(message)
六、常见问题解决方案
CAUTION
问题 1:响应 Mono
未触发处理
原因:输出通道非响应式
解决:使用 ReactiveStreamsSubscribableChannel
或添加订阅逻辑
CAUTION
问题 2:订阅数据无输出
原因:未转换 SubscriptionPublisher
解决:使用 flatMap
转换为 Flux
(参考第四节示例)
性能优化建议
复用 ExecutionGraphQlService
实例,避免重复初始化 Schema
七、完整应用示例
点击查看完整配置
kotlin
@Configuration
@EnableIntegration
class AppConfig {
// GraphQL 基础设施
@Bean
fun graphQlSource() = GraphQlSource.builder()
.schemaResources(ClassPathResource("starwars.graphqls"))
.build()
@Bean
fun graphQlService() = DefaultExecutionGraphQlService(graphQlSource())
// 网关配置
@Bean
fun graphqlGateway() = GraphQl.gateway(graphQlService())
.operationExpression("payload.query")
.variablesExpression("payload.variables")
.get()
// 集成流
@Bean
fun graphqlFlow() = IntegrationFlow
.from(MessageChannels.direct("requestChannel"))
.handle(graphqlGateway())
.transform { response: Mono<ExecutionGraphQlResponse> ->
response.flatMap { res ->
if (res.isSubscription) res.getData<SubscriptionPublisher>()
else Mono.just(res.toSpecification())
}
}
.channel("responseChannel")
.get()
}
✅ 核心优势总结:
- 统一协议:将任意消息源接入 GraphQL
- 响应式支持:原生集成 Reactor API
- 动态能力:SpEL 实现运行时参数注入
通过此教程,您已掌握在 Spring Integration 中集成 GraphQL 的核心技能。实际开发时,建议结合 Spring GraphQL 官方文档深化理解。