GraphQL のサポート

Spring Integration は、GraphQL (英語) プロトコルと対話するためのチャネルアダプターを提供します。実装は Spring for GraphQL に基づいています。

この依存関係をプロジェクトに含める必要があります。

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

GraphQL 送信 ゲートウェイ

GraphQlMessageHandler は、GraphQL querymutation または subscription 操作を実行し、その結果を生成するための送信 ゲートウェイ契約を表す AbstractReplyProducingMessageHandler 拡張機能です。operation の実行には org.springframework.graphql.ExecutionGraphQlService が必要です。これは静的に、またはリクエストメッセージに対する SpEL 式を介して構成できます。operationName はオプションであり、静的にまたは SpEL 式を介して構成することもできます。variablesExpression もオプションであり、パラメーター化された操作に使用されます。locale はオプションであり、GraphQL Java (英語) ライブラリの操作実行コンテキストに使用されます。executionId は SpEL 式を介して構成でき、デフォルトはリクエストメッセージの id ヘッダーです。

リクエストメッセージのペイロードが ExecutionGraphQlRequest のインスタンスである場合、GraphQlMessageHandler ではセットアップアクションは実行されず、そのような入力は ExecutionGraphQlService.execute() にそのまま使用されます。それ以外の場合、operationoperationNamevariablesexecutionId は、上記の SpEL 式を使用してリクエストメッセージに対して決定されます。

GraphQlMessageHandler はリアクティブストリームコンポーネントであり、ExecutionGraphQlService.execute(ExecutionGraphQlRequest) の結果として Mono<ExecutionGraphQlResponse> 応答を生成します。このような 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();
}

このような送信ゲートウェイは、HTTP 経由の GraphQL リクエストだけでなく、メッセージ内の GraphQL 操作またはその引数を生成または運ぶアップストリームエンドポイントからも使用できます。GraphQlMessageHandler 処理の結果は、アップストリームリクエストへの応答として生成されるか、統合フローでさらに処理するためにダウンストリームに送信されます。