GraphQL 支援

Spring Integration 提供了用於與 GraphQL 協議互動的通道介面卡。該實現基於 Spring for GraphQL

你需要將此依賴項新增到你的專案中

  • Maven

  • Gradle

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-graphql</artifactId>
    <version>6.4.4</version>
</dependency>
compile "org.springframework.integration:spring-integration-graphql:6.4.4"

GraphQL 出站閘道器

GraphQlMessageHandlerAbstractReplyProducingMessageHandler 的一個擴充套件,它代表著一個出站閘道器契約,用於執行 GraphQL 的 querymutationsubscription 操作併產生其結果。它需要一個 org.springframework.graphql.ExecutionGraphQlService 來執行 operation,該服務可以靜態配置,也可以透過 SpEL 表示式針對請求訊息進行配置。operationName 是可選的,也可以靜態配置或透過 SpEL 表示式配置。variablesExpression 也是可選的,用於引數化操作。locale 是可選的,用於 GraphQL Java 庫中的操作執行上下文。executionId 可以透過 SpEL 表示式配置,預設為請求訊息的 id 訊息頭。

如果請求訊息的負載是 ExecutionGraphQlRequest 的例項,則在 GraphQlMessageHandler 中不會執行任何設定操作,直接使用此輸入作為 ExecutionGraphQlService.execute() 的引數。否則,將使用上面提到的 SpEL 表示式根據請求訊息確定 operationoperationNamevariablesexecutionId

GraphQlMessageHandler 是一個響應式流元件,並作為 ExecutionGraphQlService.execute(ExecutionGraphQlRequest) 的結果產生一個 Mono<ExecutionGraphQlResponse> 回覆。當輸出通道是響應式的 ReactiveStreamsSubscribableChannel 時,框架會訂閱此 Mono;當輸出通道不是響應式的時,AbstractMessageProducingHandler 會非同步訂閱。請參閱 ExecutionGraphQlResponse 的文件,瞭解如何處理 GraphQL 操作結果。

@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();
}

這種出站閘道器不僅可以用於透過 HTTP 傳送 GraphQL 請求,也可以用於任何上游端點,只要它在訊息中產生或攜帶 GraphQL 操作或其引數。GraphQlMessageHandler 處理的結果可以作為對上游請求的回覆產生,或者向下遊傳送以便在整合流中進一步處理。