ゼロから始める 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 では複数のエンドポイントへのアクセスが必要になり、ネットワークの負荷も増加します。
主な課題点
# | 課題 | 影響 |
---|---|---|
1 | Over-fetching | 不要なデータ転送によるパフォーマンス低下 |
2 | Under-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
パッケージの役割を整理すると以下のようになります:
# | パッケージ | 役割 |
---|---|---|
1 | apollo-server-express | Apollo Server の Express 統合版 |
2 | graphql | GraphQL の核となるライブラリ |
3 | express | Web サーバーフレームワーク |
4 | typescript | TypeScript 環境 |
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();
動作確認手順
- サーバーを起動します:
bashyarn dev
- ブラウザで
http://localhost:4000/graphql
にアクセス - Apollo Studio(GraphQL Playground)が表示されます
- 以下のクエリを実行して動作確認:
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 の世界は奥深く、学びがいのある技術領域です。今回の基礎を土台に、さらに高度な機能に挑戦してみてください。
関連リンク
- review
今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
- review
ついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
- review
愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
- review
週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
- review
新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
- review
科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来