GraphQL 支持
Spring Integration 提供了与 GraphQL 协议交互的通道适配器。该实现基于 Spring for GraphQL。
你需要将这个依赖添加到你的项目中:
- Maven
- Gradle
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-graphql</artifactId>
<version>6.4.2</version>
</dependency>
compile "org.springframework.integration:spring-integration-graphql:6.4.2"
GraphQL 外向网关
GraphQlMessageHandler
是 AbstractReplyProducingMessageHandler
的扩展,表示一个出站网关契约,用于执行 GraphQL query
、mutation
或 subscription
操作并生成其结果。它需要一个 org.springframework.graphql.ExecutionGraphQlService
来执行 operation
,这可以通过静态配置或针对请求消息的 SpEL 表达式来实现。operationName
是可选的,也可以通过静态配置或 SpEL 表达式进行配置。variablesExpression
也是可选的,用于参数化操作。locale
是可选的,并在 GraphQL Java 库中用于操作执行上下文。executionId
可以通过 SpEL 表达式进行配置,默认为请求消息的 id
头。
如果请求消息的有效负载是 ExecutionGraphQlRequest
的实例,则在 GraphQlMessageHandler
中不会执行任何设置操作,此类输入将原样用于 ExecutionGraphQlService.execute()
。否则,将根据上述 SpEL 表达式针对请求消息确定 operation
、operationName
、variables
和 executionId
。
GraphQlMessageHandler
是一个反应式流组件,它产生一个 Mono<ExecutionGraphQlResponse>
回复作为 ExecutionGraphQlService.execute(ExecutionGraphQlRequest)
的结果。这样的 Mono
由框架在 ReactiveStreamsSubscribableChannel
输出通道中订阅,或者在输出通道不是反应式时由 AbstractMessageProducingHandler
异步订阅。有关如何处理 GraphQL 操作结果的详细信息,请参阅 ExecutionGraphQlResponse
的文档。
@Bean
GraphQlMessageHandlerSpec graphQlMessageHandlerSpec(ExecutionGraphQlService graphQlService) {
return GraphQl.gateway(graphQlService)
.operation("""
query HeroNameAndFriends($episode: Episode) {
hero(episode: $episode) {
name
friends {
name
}
}
}""")
.variablesExpression("{episode:'JEDI'}");
}
@Bean
IntegrationFlow graphqlQueryMessageHandlerFlow(GraphQlMessageHandler handler) {
return IntegrationFlow.from(MessageChannels.flux("inputChannel"))
.handle(handler)
.channel(c -> c.flux("resultChannel"))
.get();
}
@Bean
ExecutionGraphQlService graphQlService(GraphQlSource graphQlSource) {
return new DefaultExecutionGraphQlService(graphQlSource);
}
@Bean
GraphQlSource graphQlSource(AnnotatedControllerConfigurer annotatedDataFetcherConfigurer) {
return GraphQlSource.builder()
.schemaResources(new ClassPathResource("graphql/test-schema.graphqls"))
.configureRuntimeWiring(annotatedDataFetcherConfigurer)
.build();
}
@Bean
AnnotatedControllerConfigurer annotatedDataFetcherConfigurer() {
return new AnnotatedControllerConfigurer();
}
对于订阅操作的结果应进行特殊处理。在这种情况下,ExecutionGraphQlResponse.getData()
返回一个 SubscriptionPublisher
,必须手动订阅和处理它。或者,可以通过普通的服务激活器将其扁平映射为 FluxMessageChannel
的回复:
@ServiceActivator(inputChannel = "graphQlResultChannel", outputChannel="graphQlSubscriptionChannel")
public SubscriptionPublisher obtainSubscriptionResult(ExecutionGraphQlResponse graphQlResponse) {
return graphQlResponse.getData();
}
这种 outbound 网关不仅可以用于通过 HTTP 发送的 GraphQL 请求,还可以用于任何上游端点,这些端点在消息中生成或携带 GraphQL 操作或其参数。GraphQlMessageHandler
处理的结果可以作为对上游请求的回复产生,或者发送到下游以在集成流中进行进一步处理。