Spring for GraphQL

GraphQL アプリケーションを構築する場合は、Spring Boot の Spring for GraphQL の自動構成を利用できます。Spring for GraphQL プロジェクトは GraphQL Java [GitHub] (英語) に基づいています。少なくとも spring-boot-starter-graphql スターターが必要です。GraphQL はトランスポートに依存しないため、GraphQL API を Web 上で公開するには、アプリケーションに 1 つ以上の追加のスターターが必要です。

スターター トランスポート 実装

spring-boot-starter-web

HTTP

Spring MVC

spring-boot-starter-websocket

WebSocket

サーブレットアプリ用の WebSocket

spring-boot-starter-webflux

HTTP、WebSocket

Spring WebFlux

spring-boot-starter-rsocket

TCP、WebSocket

Spring WebFlux on Reactor Netty

GraphQL スキーマ

Spring GraphQL アプリケーションには、起動時に定義済みのスキーマが必要です。デフォルトでは、src/main/resources/graphql/** に ".graphqls" または ".gqls" スキーマファイルを書き込むことができ、Spring Boot はそれらを自動的に取得します。spring.graphql.schema.locations を使用して場所をカスタマイズし、spring.graphql.schema.file-extensions を使用してファイル拡張子をカスタマイズできます。

すべてのアプリケーションモジュール内のスキーマファイルとその場所の依存関係を Spring Boot で検出する場合は、spring.graphql.schema.locations を "classpath*:graphql/**/" に設定できます (classpath*: プレフィックスに注意してください)。

次のセクションでは、このサンプル GraphQL スキーマを検討し、2 つの型と 2 つのクエリを定義します。

type Query {
    greeting(name: String! = "Spring"): String!
    project(slug: ID!): Project
}

""" A Project in the Spring portfolio """
type Project {
    """ Unique string id used in URLs """
    slug: ID!
    """ Project name """
    name: String!
    """ URL of the git repository """
    repositoryUrl: String!
    """ Current support status """
    status: ProjectStatus!
}

enum ProjectStatus {
    """ Actively supported by the Spring team """
    ACTIVE
    """ Supported by the community """
    COMMUNITY
    """ Prototype, not officially supported yet  """
    INCUBATING
    """ Project being retired, in maintenance mode """
    ATTIC
    """ End-Of-Lifed """
    EOL
}
デフォルトでは、GraphiQL などのツールに必要なため、スキーマでフィールドイントロスペクションが許可 (英語) されます。スキーマに関する情報を公開したくない場合は、spring.graphql.schema.introspection.enabled を false に設定することでイントロスペクションを無効にできます。

GraphQL RuntimeWiring

GraphQL Java RuntimeWiring.Builder を使用して、カスタムスカラー型、ディレクティブ、型リゾルバー、DataFetcher などを登録できます。Spring 構成で RuntimeWiringConfigurer Bean を宣言して、RuntimeWiring.Builder にアクセスできます。Spring Boot はそのような Bean を検出し、GraphQlSource ビルダーに追加します。

ただし、通常、アプリケーションは DataFetcher を直接実装せず、代わりにアノテーション付きコントローラーを作成します。Spring Boot は、アノテーション付きのハンドラーメソッドを持つ @Controller クラスを自動的に検出し、DataFetcher として登録します。@Controller クラスを使用したグリーティングクエリの実装例を次に示します。

  • Java

  • Kotlin

import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;

@Controller
public class GreetingController {

	@QueryMapping
	public String greeting(@Argument String name) {
		return "Hello, " + name + "!";
	}

}
import org.springframework.graphql.data.method.annotation.Argument
import org.springframework.graphql.data.method.annotation.QueryMapping
import org.springframework.stereotype.Controller

@Controller
class GreetingController {

	@QueryMapping
	fun greeting(@Argument name: String): String {
		return "Hello, $name!"
	}

}

Querydsl および QueryByExample リポジトリのサポート

Spring Data は、Querydsl リポジトリと QueryByExample リポジトリの両方をサポートします。Spring GraphQL は、Querydsl および QueryByExample リポジトリを DataFetcher として構成できます。

@GraphQlRepository でアノテーションが付けられ、次のいずれかを継承する Spring Data リポジトリ:

  • QuerydslPredicateExecutor

  • ReactiveQuerydslPredicateExecutor

  • QueryByExampleExecutor

  • ReactiveQueryByExampleExecutor

Spring Boot によって検出され、トップレベルのクエリに一致する DataFetcher の候補と見なされます。

トランスポート

HTTP および WebSocket

GraphQL HTTP エンドポイントは、デフォルトでは HTTP POST /graphql です。また、サブスクリプションのみで Server Sent Events 経由の "text/event-stream" メディア型もサポートしています。パスは spring.graphql.path でカスタマイズできます。

Spring MVC と Spring の両方の HTTP エンドポイント WebFlux は、0 の @Order を持つ RouterFunction Bean によって提供されます。独自の RouterFunction Bean を定義する場合は、適切な @Order アノテーションを追加して、それらが正しくソートされるようにすることができます。

GraphQL WebSocket エンドポイントはデフォルトでオフになっています。有効にするには:

  • サーブレットアプリケーションの場合は、WebSocket スターター spring-boot-starter-websocket を追加します

  • WebFlux アプリケーションの場合、追加の依存関係は必要ありません

  • どちらの場合も、spring.graphql.websocket.path アプリケーションプロパティを設定する必要があります

Spring GraphQL は Web インターセプトモデルを提供します。これは、HTTP リクエストヘッダーから情報を取得して GraphQL コンテキストに設定したり、同じコンテキストから情報を取得してレスポンスヘッダーに書き込んだりする場合に非常に便利です。Spring Boot を使用すると、WebInterceptor Bean を宣言して、Web トランスポートに登録することができます。

Spring MVC および Spring WebFlux は、CORS(クロスオリジンリソースシェアリング)リクエストをサポートします。CORS は、さまざまなドメインを使用するブラウザーからアクセスされる GraphQL アプリケーションの Web 構成の重要な部分です。

Spring Boot は、spring.graphql.cors.* 名前空間で多くの構成プロパティをサポートします。設定例を次に示します。

  • プロパティ

  • YAML

spring.graphql.cors.allowed-origins=https://example.org
spring.graphql.cors.allowed-methods=GET,POST
spring.graphql.cors.max-age=1800s
spring:
  graphql:
    cors:
      allowed-origins: "https://example.org"
      allowed-methods: GET,POST
      max-age: 1800s

RSocket

RSocket は、WebSocket または TCP に加えて、トランスポートとしてもサポートされています。RSocket サーバーが構成されているが完了すると、spring.graphql.rsocket.mapping を使用して特定のルートに GraphQL ハンドラーを構成できます。例: そのマッピングを "graphql" として構成すると、RSocketGraphQlClient でリクエストを送信するときにルートとして使用できるようになります。

Spring Boot は、コンポーネントに挿入できる RSocketGraphQlClient.Builder<?> Bean を自動構成します。

  • Java

  • Kotlin

@Component
public class RSocketGraphQlClientExample {

	private final RSocketGraphQlClient graphQlClient;

	public RSocketGraphQlClientExample(RSocketGraphQlClient.Builder<?> builder) {
		this.graphQlClient = builder.tcp("example.spring.io", 8181).route("graphql").build();
	}
@Component
class RSocketGraphQlClientExample(private val builder: RSocketGraphQlClient.Builder<*>) {

次に、リクエストを送信します: include-code::RSocketGraphQlClientExample[tag=request]

例外処理

Spring GraphQL を使用すると、アプリケーションは、順次呼び出される 1 つ以上の Spring DataFetcherExceptionResolver コンポーネントを登録できます。例外は、graphql.GraphQLError オブジェクトのリストに解決する必要があります。Spring GraphQL 例外処理ドキュメントを参照してください。Spring Boot は DataFetcherExceptionResolver Bean を自動的に検出し、GraphQlSource.Builder に登録します。

GraphiQL とスキーマプリンター

Spring GraphQL は、GraphQLAPI を使用または開発する際に開発者を支援するためのインフラストラクチャーを提供します。

Spring GraphQL には、デフォルトで "/graphiql" で公開されるデフォルトの GraphiQL [GitHub] (英語) ページが付属しています。このページはデフォルトで無効になっており、spring.graphql.graphiql.enabled プロパティでオンにできます。このようなページを公開する多くのアプリケーションは、カスタムビルドを好みます。デフォルトの実装は開発中に非常に役立ちます。これが、開発中に spring-boot-devtools で自動的に公開される理由です。

spring.graphql.schema.printer.enabled プロパティが有効になっている場合は、/graphql/schema で GraphQL スキーマをテキスト形式で公開することもできます。