T-CREATOR

ゼロから始める Apollo 開発環境 - セットアップから初回クエリまで

ゼロから始める Apollo 開発環境 - セットアップから初回クエリまで

GraphQL の世界に足を踏み入れることで、API 開発の新しい可能性が広がります。本記事では、Apollo GraphQL の開発環境をゼロから構築し、実際に動作する初回クエリまでの道のりをご案内いたします。

初心者の方でも安心して進められるよう、各ステップを丁寧に解説していきますので、一緒に学んでいきましょう。

背景 - Apollo GraphQL とは何か

Apollo GraphQL は、現代の Web 開発において注目されているデータクエリ言語「GraphQL」を効率的に活用するためのプラットフォームです。Facebook によって OSS として公開された GraphQL を、より実用的で開発しやすい形にしたのが Apollo と言えるでしょう。

以下の図で、Apollo GraphQL の基本構造を確認してみましょう。

mermaidflowchart TD
  client[Apollo Client] -->|GraphQLクエリ| server[Apollo Server]
  server -->|スキーマ検証| schema[GraphQL Schema]
  server -->|データ取得| resolver[Resolvers]
  resolver -->|結果| db[(Database)]
  server -->|JSON レスポンス| client

上記の図が示すように、Apollo Client からのクエリは、Apollo Server で処理され、定義されたスキーマとリゾルバーを通してデータベースからデータを取得します。

Apollo GraphQL の特徴

#特徴説明
1型安全性TypeScript との親和性が高く、開発時の型チェックが可能
2キャッシュ機能自動的なデータキャッシュで高パフォーマンスを実現
3開発ツールApollo Studio 等の充実した開発環境
4エコシステム豊富なプラグインと拡張機能

これらの特徴により、従来の REST API ベースの開発と比較して、より効率的で保守性の高いアプリケーション開発が可能になります。

課題 - 従来の REST API の問題点

REST API を使った開発では、以下のような課題に直面することがあります。

データの過不足問題

REST API では、エンドポイントごとに決められた形式のデータが返されるため、必要以上のデータを取得してしまったり、逆に必要なデータが不足してしまうケースがしばしば発生します。

mermaidsequenceDiagram
  participant C as Client
  participant API1 as /api/users
  participant API2 as /api/posts
  participant API3 as /api/comments

  C->>API1: ユーザー情報取得
  API1-->>C: 全ユーザーデータ(不要な項目も含む)
  C->>API2: 投稿データ取得
  API2-->>C: 投稿一覧
  C->>API3: コメント取得
  API3-->>C: コメント一覧

  Note over C: 3回のAPIコールが必要

このシーケンス図で分かるように、REST API では複数のエンドポイントへのアクセスが必要になり、ネットワークの負荷も増加します。

主な課題点

#課題影響
1Over-fetching不要なデータ転送によるパフォーマンス低下
2Under-fetching複数リクエストによるネットワーク負荷
3エンドポイント増加API 管理の複雑化
4バージョニング問題後方互換性の維持が困難

これらの課題は、特にモバイルアプリケーションや SPA など、ネットワーク効率が重要なアプリケーションで顕著に現れます。

解決策 - Apollo GraphQL の優位性

Apollo GraphQL は、前述の REST API の課題を解決する革新的なアプローチを提供します。

単一エンドポイントでの効率的なデータ取得

GraphQL の最大の特徴は、単一のエンドポイントで必要なデータだけを効率的に取得できることです。

mermaidsequenceDiagram
  participant C as Apollo Client
  participant S as Apollo Server
  participant DB as Database

  C->>S: 単一GraphQLクエリ
  Note over C,S: { user { name, posts { title } } }
  S->>DB: 最適化されたクエリ実行
  DB-->>S: 必要なデータのみ
  S-->>C: 要求されたデータ構造で返却

  Note over C: 1回のAPIコールで完結

このように、クライアントが必要とするデータの形式を指定することで、効率的なデータ取得が実現できます。

Apollo GraphQL の主な優位性

#優位性詳細説明
1柔軟なデータ取得クライアントが必要なフィールドのみを指定可能
2強力な型システムスキーマベースの開発で型安全性を確保
3リアルタイム対応Subscription によるリアルタイムデータ更新
4開発効率向上自動生成される型定義とドキュメント
5キャッシュ最適化インテリジェントなクライアントサイドキャッシュ

これらの機能により、開発チームはより高品質なアプリケーションを短期間で構築できるようになります。

環境構築手順

Apollo GraphQL 開発環境の構築を段階的に進めていきましょう。

Node.js 環境の準備

まず、Node.js 環境が整っているか確認します。Apollo GraphQL は Node.js 14 以上をサポートしています。

javascript// Node.jsバージョン確認
node --version
npm --version

バージョンが古い場合は、Node.js 公式サイトから最新の LTS 版をインストールしてください。

プロジェクトの初期化

新しいプロジェクトディレクトリを作成し、package.json を初期化します。

bashmkdir apollo-tutorial
cd apollo-tutorial
yarn init -y

この段階で、プロジェクトの基本構造が準備できました。

Apollo Server のセットアップ

Apollo Server に必要なパッケージをインストールします。

bashyarn add apollo-server-express graphql express
yarn add -D @types/node typescript ts-node nodemon

パッケージの役割を整理すると以下のようになります:

#パッケージ役割
1apollo-server-expressApollo Server の Express 統合版
2graphqlGraphQL の核となるライブラリ
3expressWeb サーバーフレームワーク
4typescriptTypeScript 環境

TypeScript 設定ファイルの作成

TypeScript 開発環境を整備するため、設定ファイルを作成します。

json{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "lib": ["ES2020"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

この設定により、TypeScript コンパイラが適切に動作し、型安全な開発が可能になります。

Apollo Client のセットアップ

クライアントサイドで Apollo Client を使用するためのパッケージもインストールしておきましょう。

bashyarn add @apollo/client react react-dom
yarn add -D @types/react @types/react-dom

これで、サーバーサイドとクライアントサイド両方の Apollo 環境が準備できました。

具体例 - 初回クエリの実装

実際に動作する Apollo GraphQL アプリケーションを構築していきます。

スキーマ定義

まず、GraphQL スキーマを定義します。これは API の設計図のような役割を果たします。

typescript// src/schema.ts
import { gql } from 'apollo-server-express';

export const typeDefs = gql`
  type User {
    id: ID!
    name: String!
    email: String!
    posts: [Post!]!
  }

  type Post {
    id: ID!
    title: String!
    content: String!
    author: User!
  }

  type Query {
    users: [User!]!
    user(id: ID!): User
    posts: [Post!]!
  }
`;

このスキーマでは、ユーザーと投稿の関係性を定義し、どのようなクエリが可能かを宣言しています。

リゾルバーの作成

次に、スキーマで定義されたクエリに対する実際の処理を記述するリゾルバーを作成します。

typescript// src/resolvers.ts
interface User {
  id: string;
  name: string;
  email: string;
}

interface Post {
  id: string;
  title: string;
  content: string;
  authorId: string;
}

// サンプルデータ
const users: User[] = [
  {
    id: '1',
    name: '田中太郎',
    email: 'tanaka@example.com',
  },
  { id: '2', name: '佐藤花子', email: 'sato@example.com' },
];

const posts: Post[] = [
  {
    id: '1',
    title: 'Apollo入門',
    content: 'GraphQLを学ぼう',
    authorId: '1',
  },
  {
    id: '2',
    title: 'React Tips',
    content: '効率的な開発方法',
    authorId: '2',
  },
];

続いて、実際のリゾルバー関数を定義します。

typescript// src/resolvers.ts(続き)
export const resolvers = {
  Query: {
    users: () => users,
    user: (_: any, { id }: { id: string }) => {
      return users.find((user) => user.id === id);
    },
    posts: () => posts,
  },

  User: {
    posts: (parent: User) => {
      return posts.filter(
        (post) => post.authorId === parent.id
      );
    },
  },

  Post: {
    author: (parent: Post) => {
      return users.find(
        (user) => user.id === parent.authorId
      );
    },
  },
};

リゾルバーでは、各フィールドに対するデータ取得ロジックを定義します。関連データの取得も自動的に処理されます。

Apollo Server の起動設定

サーバー起動のためのメインファイルを作成します。

typescript// src/server.ts
import express from 'express';
import { ApolloServer } from 'apollo-server-express';
import { typeDefs } from './schema';
import { resolvers } from './resolvers';

async function startServer() {
  const app = express();

  const server = new ApolloServer({
    typeDefs,
    resolvers,
    introspection: true,
    playground: true,
  });

  await server.start();
  server.applyMiddleware({ app });

  const PORT = process.env.PORT || 4000;

  app.listen(PORT, () => {
    console.log(
      `🚀 サーバーが起動しました: http://localhost:${PORT}${server.graphqlPath}`
    );
  });
}

startServer().catch((error) => {
  console.error('サーバー起動エラー:', error);
});

package.json への起動スクリプト追加

開発効率を向上させるため、起動スクリプトを追加します。

json{
  "scripts": {
    "dev": "nodemon --exec ts-node src/server.ts",
    "build": "tsc",
    "start": "node dist/server.js"
  }
}

これで、yarn devコマンドでサーバーが起動できるようになります。

クライアントサイドの実装

Apollo Client を使用したフロントエンド実装を行います。

typescript// src/client.ts
import {
  ApolloClient,
  InMemoryCache,
  gql,
} from '@apollo/client';

// Apollo Clientの初期化
const client = new ApolloClient({
  uri: 'http://localhost:4000/graphql',
  cache: new InMemoryCache(),
});

// 基本的なクエリ定義
const GET_USERS = gql`
  query GetUsers {
    users {
      id
      name
      email
      posts {
        id
        title
      }
    }
  }
`;

実際にクエリを実行する関数を作成します。

typescript// src/client.ts(続き)
async function fetchUsers() {
  try {
    const result = await client.query({
      query: GET_USERS,
    });

    console.log(
      '取得したユーザーデータ:',
      result.data.users
    );
    return result.data.users;
  } catch (error) {
    console.error('クエリ実行エラー:', error);
    throw error;
  }
}

// 関数の実行
fetchUsers();

動作確認手順

  1. サーバーを起動します:
bashyarn dev
  1. ブラウザで http:​/​​/​localhost:4000​/​graphql にアクセス
  2. Apollo Studio(GraphQL Playground)が表示されます
  3. 以下のクエリを実行して動作確認:
graphqlquery {
  users {
    id
    name
    email
    posts {
      title
    }
  }
}

期待される結果:

json{
  "data": {
    "users": [
      {
        "id": "1",
        "name": "田中太郎",
        "email": "tanaka@example.com",
        "posts": [
          {
            "title": "Apollo入門"
          }
        ]
      },
      {
        "id": "2",
        "name": "佐藤花子",
        "email": "sato@example.com",
        "posts": [
          {
            "title": "React Tips"
          }
        ]
      }
    ]
  }
}

このレスポンスが確認できれば、Apollo GraphQL 環境が正常に動作していることが確認できます。

まとめ

本記事では、Apollo GraphQL の開発環境をゼロから構築し、初回クエリの実行まで一通り体験していただきました。

REST API の課題を解決する GraphQL の特性と、それを活用しやすくする Apollo の機能により、効率的な API 開発が可能になることをご理解いただけたでしょう。

今回学んだポイント

  • Apollo GraphQL の基本概念と構造
  • REST API の課題と GraphQL による解決策
  • 実際の開発環境構築手順
  • スキーマ定義からクエリ実行までの流れ

次のステップとしては、より複雑なクエリや Mutation(データ更新)、Subscription(リアルタイム更新)などの機能を探求していくことをお勧めします。

Apollo GraphQL の世界は奥深く、学びがいのある技術領域です。今回の基礎を土台に、さらに高度な機能に挑戦してみてください。

関連リンク