Spring Boot GraphQL入門!Query・Mutation・Subscriptionの基本を初心者向けに解説
新人
「先輩、最近よく聞くGraphQLって何ですか?REST APIとはどう違うんですか?」
先輩
「良いところに気がついたね。GraphQLはAPIを扱う新しい方法で、必要なデータだけを取得できるのが特徴なんだ。REST APIでは複数のエンドポイントにアクセスする必要があるけれど、GraphQLでは一つのエンドポイントで必要なデータを柔軟に取得できるんだよ。」
新人
「なるほど、効率が良さそうですね。でも仕組みがよく分からないです。」
先輩
「それじゃあ、GraphQLの基本構造を一緒に見ていこうか。特にGraphQL Query、GraphQL Mutation、Subscriptionの3つが重要なんだ。」
1. GraphQLとは?
GraphQLはFacebookが開発したAPIのクエリ言語で、今ではSpring Boot GraphQLでも多く利用されています。従来のREST APIと比べて大きな特徴は「必要なデータだけを取得できる」ことです。RESTではクライアントが複数のエンドポイントにアクセスしないと揃わない情報もありますが、GraphQLではひとつのリクエストでまとめてデータを取得できます。
例えば、ユーザー情報と投稿記事を取得したい場合、REST APIでは/usersと/postsの二つにアクセスしなければなりません。しかしGraphQLでは一つのクエリで両方を指定できるため、ネットワーク通信が効率化されます。これはモバイルアプリや複雑なWebアプリの開発で特に便利です。
また、GraphQLはスキーマ駆動型で、サーバーとクライアントの間でデータ構造を明確に定義できます。これにより初心者でもAPIの使い方を理解しやすくなり、IDEの補完機能なども活用できるようになります。
2. GraphQLスキーマと基本構造の概要
GraphQLの基本構造は大きく分けて「Query」「Mutation」「Subscription」の三つです。これらはSpring Boot GraphQLでも同じように使われます。それぞれの役割を理解すると、API設計の全体像がつかめます。
Query(クエリ)
GraphQL Queryは「データを取得する処理」です。REST APIのGETリクエストに相当します。必要なフィールドだけを選択して指定できるため、不要なデータが送られてくることはありません。
@Controller
public class UserController {
@QueryMapping
public User getUserById(@Argument Long id) {
return new User(id, "Taro", "taro@example.com");
}
}
この例では、GraphQL Queryを使ってユーザーIDに対応するユーザー情報を取得します。Spring Boot GraphQLと@Controllerを組み合わせることで簡単に定義できます。
Mutation(ミューテーション)
GraphQL Mutationは「データを変更する処理」です。REST APIでいうPOSTやPUTに近い役割を持ちます。データベースに新しいレコードを追加したり、既存のデータを更新する際に利用します。
@Controller
public class UserController {
@MutationMapping
public User createUser(@Argument String name, @Argument String email) {
return new User(1L, name, email);
}
}
この例では、GraphQL Mutationを利用して新しいユーザーを作成しています。リクエスト時に必要な引数を渡すことで、クライアントは柔軟にデータを登録できます。
Subscription(サブスクリプション)
GraphQL Subscriptionは「リアルタイム通知の仕組み」です。これはREST APIには存在しない大きな特徴で、WebSocketを利用してクライアントにイベントをプッシュ通知できます。チャットアプリや株価の更新など、リアルタイム性が求められるケースで非常に役立ちます。
@Controller
public class UserController {
@SubscriptionMapping
public Flux<User> userCreated() {
return Flux.interval(Duration.ofSeconds(1))
.map(i -> new User(i, "User" + i, "user" + i + "@example.com"));
}
}
このコードは新しいユーザーが作成されるたびにリアルタイムで通知する仕組みを表しています。Spring Boot GraphQLではFluxを使って非同期ストリームを扱い、Subscriptionを簡単に実装できます。
全体像の整理
まとめると、GraphQL Queryは「取得」、GraphQL Mutationは「更新や作成」、Subscriptionは「リアルタイム通知」という役割を持ちます。これらを組み合わせることで、効率的で柔軟なAPIを実現できるのです。
pleiadesとGradleの環境を使えば、初心者でもSpring Boot GraphQLを手軽に試すことができます。特に@Controllerを用いたシンプルな記述は、学習のハードルを大きく下げてくれるでしょう。
3. Query型の定義方法と実装例
ここからはSpring Boot API開発で実際に使われるGraphQL 実装例を見ていきましょう。まずはQuery型の定義方法です。Query型はデータを取得するための型で、ユーザー情報や商品情報などを必要に応じて取り出すことができます。初心者の方はRESTのGETメソッドと比較すると理解しやすいでしょう。Queryでは返してほしいフィールドをクライアントが自由に選べるので、無駄なデータを送受信しない点が大きなメリットです。
例えば、ユーザーIDを指定してユーザー情報を取得するQuery型を定義する場合、次のようにスキーマとコントローラを用意します。開発環境はpleiadesとGradleで進め、依存関係はpleiadesから追加します。
@Controller
public class UserQueryController {
@QueryMapping
public User findUserById(@Argument Long id) {
return new User(id, "Hanako", "hanako@example.com");
}
}
このGraphQL 実装例では、@Controllerを利用してQueryMappingを定義しています。pleiadesでGradleプロジェクトを作成すれば、補完機能を活用しながらスムーズに実装できます。
4. Mutation型の定義方法と実装例(データの追加・更新・削除の例)
次にGraphQL Mutationの定義方法を確認しましょう。Mutationはデータを追加したり更新したり削除するための型です。REST APIにおけるPOST、PUT、DELETEに近い役割を持ちます。Queryと違って、サーバー上の状態を変更する点がポイントです。Spring Boot API開発でユーザーを登録する例を考えてみます。
@Controller
public class UserMutationController {
@MutationMapping
public User addUser(@Argument String name, @Argument String email) {
return new User(100L, name, email);
}
@MutationMapping
public User updateUser(@Argument Long id, @Argument String name) {
return new User(id, name, "updated@example.com");
}
@MutationMapping
public boolean deleteUser(@Argument Long id) {
return true;
}
}
このGraphQL 実装例では、三つのMutationを用意しています。ひとつ目は新規ユーザーを追加する処理、二つ目は既存ユーザーの名前を更新する処理、三つ目はユーザーを削除する処理です。Queryとの違いは、取得ではなくサーバー側のデータを変更する点です。これにより、フロントエンドは一貫した仕組みでデータの追加や更新を操作でき、効率の良いAPI開発が可能となります。
5. Spring BootでのGraphQLスキーマファイル作成手順
GraphQLスキーマ定義は非常に重要で、クライアントとサーバーが共通のルールを理解するための契約書のような役割を持っています。Spring Boot GraphQLでは通常、src/main/resources/graphql配下に.graphqlsファイルを配置します。このファイルにQueryやMutationの構造を定義することで、フロントエンドとバックエンドが同じデータモデルを共有できるようになります。
例えば、ユーザー情報を扱う場合のGraphQLスキーマ定義は次のようになります。
type User {
id: ID!
name: String!
email: String!
}
type Query {
findUserById(id: ID!): User
}
type Mutation {
addUser(name: String!, email: String!): User
updateUser(id: ID!, name: String!): User
deleteUser(id: ID!): Boolean
}
このGraphQLスキーマ定義では、User型を定義し、Queryでユーザー取得、Mutationで追加や更新や削除を行えるようにしています。Spring Boot API開発ではこのようにスキーマを定義しておくと、開発者全員が共通のデータ構造を参照でき、後から機能を拡張する際にも安心です。
pleiades環境でGraphQLスキーマファイルを追加する際は、リソースフォルダを正しく作成し、その中に.graphqlsファイルを配置することが大切です。Gradleでのビルド時にも自動的に認識され、アプリケーション実行時にGraphQLエンドポイントに反映されます。
これでSpring Boot GraphQLを用いたQueryとMutationの仕組みを実際に試す準備が整いました。GraphQLスキーマ定義をきちんと理解しておけば、API開発の効率は飛躍的に向上します。
6. Subscription型の定義方法と実装例(リアルタイム通信のイメージ)
ここではGraphQL Subscriptionの定義方法を解説します。GraphQL Subscriptionは「リアルタイム通信」を可能にする仕組みで、クライアントとサーバー間で継続的にデータをやり取りできます。REST APIでは通常のHTTP通信では新しいデータを自動的に受け取ることはできませんが、GraphQL SubscriptionではWebSocketを利用することでイベントを即座に取得できます。
Spring Boot GraphQLで実装する場合、@Controllerと@SubscriptionMappingを利用してFlux型のストリームを返すようにします。これにより、一定間隔で新しいデータを生成し続け、クライアント側は購読状態を維持することで最新の情報を受け取れます。
@Controller
public class UserSubscriptionController {
@SubscriptionMapping
public Flux<User> onUserAdded() {
return Flux.interval(Duration.ofSeconds(3))
.map(i -> new User(i, "User" + i, "user" + i + "@example.com"));
}
}
このGraphQL Subscriptionの実装例では、三秒ごとに新しいユーザーを生成して通知しています。リアルタイム通信を体感するには、フロントエンドからSubscriptionを送信し、サーバーからイベントが流れてくる様子を確認するのが最もわかりやすいでしょう。例えばチャットアプリで新しいメッセージを即時に受け取るイメージです。
7. 実際にGraphQLクエリやMutation、Subscriptionを送信してデータを取得する流れ
次にSpring Boot GraphQL クエリやMutation、Subscriptionを実際に送信して動作を確認する流れを見ていきましょう。pleiades + Gradleで環境を構築した後、アプリケーションを起動するとデフォルトで/graphqlエンドポイントが利用可能になります。ここにクエリを送信することで、API開発で定義した処理が実行されます。
Queryリクエスト例
query {
findUserById(id: 1) {
id
name
email
}
}
Queryレスポンス例
{
"data": {
"findUserById": {
"id": 1,
"name": "Hanako",
"email": "hanako@example.com"
}
}
}
Mutationリクエスト例
mutation {
addUser(name: "Taro", email: "taro@example.com") {
id
name
email
}
}
Mutationレスポンス例
{
"data": {
"addUser": {
"id": 100,
"name": "Taro",
"email": "taro@example.com"
}
}
}
Subscriptionリクエスト例
subscription {
onUserAdded {
id
name
email
}
}
Subscriptionレスポンス例(継続的に流れてくるデータ)
{
"data": {
"onUserAdded": {
"id": 1,
"name": "User1",
"email": "user1@example.com"
}
}
}
{
"data": {
"onUserAdded": {
"id": 2,
"name": "User2",
"email": "user2@example.com"
}
}
}
このようにGraphQL Subscriptionではクライアントが接続を維持する限り、サーバーからイベントが継続的にプッシュされます。Spring Boot GraphQL クエリとMutationに比べて、Subscriptionはリアルタイム性が重視されるアプリケーションに向いています。初心者の方でも、チャットや通知システムの仕組みをイメージすると理解しやすいでしょう。
8. GraphQLを学習する上でのおすすめの方法
最後にGraphQLを学習する上でのおすすめの方法を紹介します。まずはSpring Boot GraphQLの基本的なQueryとMutationを実装し、小さなAPI開発から始めるのが良いでしょう。実際にpleiades + Gradle環境でプロジェクトを作成し、@Controllerを使ってコードを書いてみることで、理論だけでは分からないポイントを体験できます。
次に、GraphQLスキーマ定義をしっかり理解しましょう。スキーマはプロジェクト全体の共通言語となり、クライアントとサーバーの間での誤解を防ぎます。さらに、GraphQL Subscriptionを試してみることでリアルタイム通信の仕組みを学ぶことができます。これは従来のREST APIにはない大きな魅力です。
学習を続ける際は、小さなサンプルアプリを作り、GraphQL クエリやMutationを少しずつ拡張していくと理解が深まります。例えば、ユーザー情報だけでなく投稿やコメントなど複数のデータを扱うAPIを設計してみると、実際のアプリケーション開発に近い経験が得られます。
また、GraphQLを扱う際にはドキュメントや公式の仕様を参照することも大切です。Spring Boot GraphQLのリファレンスやチュートリアルは初心者でも取り組みやすく、基本を固めるのに役立ちます。最終的には、クエリやMutationに加えてGraphQL Subscriptionも自在に使えるようになれば、モダンなAPI開発に必要なスキルが身についていると言えるでしょう。