クライアントが必要なものを正確に要求できる強力なAPIをどうやって作成するか、考えたことはありませんか?それがGraphQLの魔法であり、Apollo Serverを使えば、思っているよりも簡単に構築できます!RESTの厳格なエンドポイントにうんざりしているなら、GraphQLは柔軟性を提供し、Apollo Serverはその実現に最適なツールです。この対話形式のチュートリアルでは、プロジェクトの初期化からクエリやミューテーションのテストまで、Apollo Serverを使ってGraphQLサーバーをセットアップする手順を説明します。JavaScriptを使っている場合でもTypeScriptを使っている場合でも、すぐに動作するサーバーが手に入ります。さあ、GraphQLとApollo Serverを使って素晴らしいものを作りましょう!
開発チームが最大限の生産性で協力できる、統合されたオールインワンプラットフォームが欲しいですか?
Apidogはあなたのあらゆる要求に応え、Postmanをはるかに手頃な価格で置き換えます!
GraphQLとApollo Serverを選ぶ理由
作業に取り掛かる前に、なぜGraphQLとApollo Serverがこれほどダイナミックなコンビなのかについて話しましょう。2012年にFacebookによって開発され、2015年にオープンソース化されたGraphQLは、クライアントが特定のデータを要求できるようにするAPI用のクエリ言語であり、REST APIでよく見られる過剰なフェッチや不足しているフェッチを削減します。複数のエンドポイントの代わりに、カスタマイズされた応答を提供する1つのスマートなエンドポイントがあります。これは効率的で柔軟性があり、複雑なデータニーズを持つ現代のアプリケーションに最適です。
そして、Apollo GraphQLが提供するオープンソースのコミュニティ主導型GraphQLサーバーであるApollo Serverが登場します。これは本番環境に対応しており、Node.jsをサポートし、MongoDBやPostgreSQLのようなデータベースとシームレスに統合できます。スキーマステッチング、キャッシュ、リアルタイムサブスクリプションなどの機能により、スケーラブルなAPIを構築するためのワンストップショップです。さらに、初心者にも優しく、プロにとっても強力です。Express-GraphQLのような代替品と比較して、Apollo Serverはより優れたパフォーマンス監視と簡単なセットアップを提供します。ブログ、Eコマースサイト、またはモバイルバックエンドを構築している場合、この組み合わせは時間と手間を省いてくれます。ワクワクしますか?プロジェクトをセットアップしましょう!
JavaScriptまたはTypeScriptでプロジェクトをセットアップする
まず、基盤を構築しましょう。Node.jsプロジェクトをセットアップし、必要なパッケージをインストールします。シンプルさのためにJavaScriptを選択することも、型安全性のためにTypeScriptを選択することもできます。どちらもApollo Serverでうまく機能します。
ステップ1:プロジェクトの初期化
新しいフォルダを作成する:
- ターミナルを開き、プロジェクトディレクトリを作成します。
mkdir graphql-apollo-server
cd graphql-apollo-server
Node.jsを初期化する:
- 次のコマンドを実行します。
npm init -y
npm pkg set type="module"- これにより、依存関係を管理するための
package.jsonファイルが作成され、ES Modulesを使用するプロジェクトがセットアップされます。
ステップ2:依存関係のインストール
Apollo Serverには、サーバー用の@apollo/serverと、コアのGraphQLライブラリ用のgraphqlという2つの主要なパッケージが必要です。TypeScriptの場合、型とビルドステップを追加します。
依存関係をインストールする:
npm install @apollo/server graphql
JavaScriptの場合:
package.jsonファイルのデフォルトのscriptsエントリを、これらのtypeとscriptsエントリに置き換えるだけです。
{
// ...etc.
"type": "module",
"scripts": {
"start": "node index.js"
}
// other dependencies
}TypeScriptの場合(推奨):
1. TypeScriptを初期化します。
npm install --save-dev typescript @types/node- ルートディレクトリに
tsconfig.jsonファイルを作成し、次のように編集します。
{
"compilerOptions": {
"rootDirs": ["src"],
"outDir": "dist",
"lib": ["es2023"],
"target": "es2023",
"module": "esnext",
"moduleResolution": "node",
"esModuleInterop": true,
"types": ["node"]
}
}2. 最後に、package.jsonファイルのscriptsエントリを、次のtypeとscriptsエントリに置き換えます。
{
// ...etc.
"type": "module",
"scripts": {
"compile": "tsc",
"start": "npm run compile && node ./dist/index.js"
}
// other dependencies
}
プロのヒント:TypeScriptを初めて使う場合、スキーマとリゾルバーに型安全性が追加され、早期にエラーを捕捉できます。JavaScriptはプロトタイプ作成にはより迅速です。プロジェクトの規模に基づいて選択してください。
ステップ3:サーバーファイルの作成
プロジェクトのルートにsrcフォルダを作成し、その新しいフォルダ内にindex.ts(JavaScriptの場合はindex.js)ファイルを追加します。ここにスキーマとリゾルバーを定義します。

シンプルなクエリを試す
最初のクエリ、シンプルな「hello」メッセージを構築しましょう。これはGraphQLの型定義(スキーマ)とリゾルバー(データをフェッチする関数)を紹介します。
GraphQLスキーマを定義する
スキーマはAPIの設計図です。graphql-tag(@apollo/serverに含まれる)のgqlタグを使用して定義します。
index.ts(またはindex.js)で:
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
// Define GraphQL schema
const typeDefs = `
type Query {
hello: String
}
`;
// Define resolvers
const resolvers = {
Query: {
hello: () => "Hello! Welcome to my server",
},
};
// Create and start the server
const server = new ApolloServer({ typeDefs, resolvers });
const { url } = await startStandaloneServer(server, {
listen: { port: 4000 },
});
console.log(`🚀 Server ready at: ${url}`);
JavaScriptの場合、型をインポートします:
const { ApolloServer } = '@apollo/server';
const { startStandaloneServer } = '@apollo/server/standalone';
// Rest is the same
サーバーを実行する
サーバーを起動します:
node index.js # For JavaScript
npm start # For TypeScript
ブラウザでhttp://localhost:4000にアクセスしてください。クエリをテストするためのWebベースのIDEであるGraphQL Playgroundが表示されます。

クエリをテストする
Playgroundの左側のパネルで、このクエリを実行します:
query {
hello
}
「Execute」をクリックします。右側に次のように表示されます:
{
"data": {
"hello": "Hello! Welcome to my server"
}
}

成功です!このシンプルなクエリは、GraphQLの基本を示しています。`hello`フィールドが文字列を返す`Query`型です。リゾルバーはデータを提供する「頭脳」であり、この場合は静的なメッセージです。これはセットアップを確認するための素晴らしい出発点です。
複雑な型を持つクエリをテストする
次に、カスタム型を使って深みを持たせましょう。`Book`型と、書籍のリストを取得するクエリを作成します。これにより、GraphQLが構造化データをどのように扱うかを示します。
スキーマを更新する
typeDefsをBook型を含むように変更します:
const typeDefs = gql`
type Book {
title: String
author: String
}
type Query {
books: [Book]
}
`;
サンプルデータを追加する
typeDefsの下に、新しいBook型用の次のサンプルデータを追加します。
// Sample data
const books = [
{
title: 'The Awakening',
author: 'Kate Chopin',
},
{
title: 'City of Glass',
author: 'Paul Auster',
},
];リゾルバーを更新する
リゾルバーの内容を、books型用に次のように置き換えます:
const resolvers = {
Query: {
books: () => books
}
};
サーバーを再起動し、Playgroundに戻ります。
クエリをテストする
実行:
query GetBooks {
books {
title
author
}
}
結果:
{
"data": {
"books": [
{
"title": "The Awakening",
"author": "Kate Chopin"
},
{
"title": "City of Glass",
"author": "Paul Auster"
}
]
}
}
すごいでしょう?このクエリは`Book`オブジェクトの配列を取得します。GraphQLを使用すると、クライアントは必要なフィールドを正確に指定できます。それ以上でもそれ以下でもありません。`author`を省略すると、タイトルのみが返されます。この柔軟性こそが、データ量の多いアプリでGraphQLがRESTを凌駕する理由です。

データを追加するミューテーションをテストする
クエリは読み取り用ですが、ミューテーションは書き込み用です。新しい書籍を作成するミューテーションを追加し、GraphQLがデータの作成をどのように処理するかを示しましょう。
スキーマを更新する
Mutation型を追加します:
const typeDefs = `
type Book {
title: String
author: String
}
type Query {
books: [Book]
}
type Mutation {
createBook(title: String!, author: String!): Book
}
`;
!は必須フィールドを意味します。
リゾルバーを更新する
const resolvers = {
Query: {
books: () => books,
},
Mutation: {
createBook: (_: any, { title, author }: { title: string; author: string }) => {
const newBook = { title, author };
books.push(newBook);
return newBook;
}
}
};
ミューテーションをテストする
Playgroundで、次を実行します:
mutation CreateBook{
createBook(title: "Harry Potter", author: "J.K Rowling") {
author
title
}
}
結果:
{
"data": {
"createBook": {
"title": "Harry Potter",
"author": "J.K Rowling"
}
}
}

確認のため、GetBooksクエリを再実行します:
query GetBooks {
books {
title
author
}
}
結果:
{
"data": {
"books": [
{
"title": "The Awakening",
"author": "Kate Chopin"
},
{
"title": "City of Glass",
"author": "Paul Auster"
},
{
"title": "Harry Potter",
"author": "J.K Rowling"
}
]
}
}

新しい書籍が追加されました!ミューテーションは作成されたデータを返し、クライアントは即座にフィードバックを得ることができます。本番環境では、永続化のためにMongoDBのようなDBに接続してください。
JavaScript vs TypeScript:どちらを選ぶべきか?迅速なプロトタイプ作成にはJavaScriptで十分です。ボイラープレートが少なくて済みます。しかし、大規模なプロジェクトでは、TypeScriptがスキーマとリゾルバーの型安全性で輝きを放ちます。TSは早期にエラーを検出し、**GraphQL**サーバーをより堅牢にします。
複雑さの追加:IDと引数付きクエリ
これを現実のものにするために、書籍にIDを追加し、タイトルで取得するクエリを追加します。
スキーマを更新します:
const typeDefs = `
type Book {
id: ID!
title: String
author: String
}
type Query {
books: [Book]
book(title: String!): Book
}
type Mutation {
createBook(title: String!, author: String!): Book
}
`;データとリゾルバーを更新します:
// Sample data
const books = [
{
id: 1,
title: 'The Awakening',
author: 'Kate Chopin',
},
{
id: 2,
title: 'City of Glass',
author: 'Paul Auster',
},
];
// Resolvers
const resolvers = {
Query: {
books: () => books,
book: (_: any, { title }: { title: string }) => books.find(book => book.title === title),
},
Mutation: {
createBook: (_: any, { title, author }: { title: string; author: string }) => {
const newBook = { id: books.length + 1, title, author };
books.push(newBook);
return newBook;
}
}
};
クエリをテストします:
query GetBook {
book(title: "The Awakening") {
id
title
author
}
}
結果:
{
"data": {
"book": {
"id": "1",
"title": "The Awakening",
"author": "Kate Chopin"
}
}
}
これはクエリ内の引数を示しており、クライアントがデータを効率的にフィルタリングできるようにします。

GraphQLとApollo Serverのベストプラクティス
- スキーマ設計:複数のファイルでモジュール化を維持します。
- エラー処理:カスタムエラーには
ApolloErrorを使用します。 - パフォーマンス:
@apollo/cache-controlでキャッシュを有効にします。 - サブスクリプション:
apollo-server-expressでリアルタイム機能を追加します。 - モニタリング:メトリクスにはApollo Studioを使用します。
よくある問題のトラブルシューティング
- サーバーが起動しない?Nodeのバージョン(14以上)と依存関係を確認してください。
- クエリエラー?スキーマとリゾルバーの一致を確認してください。
- CORSの問題?サーバーオプションに
{ cors: { origin: '*' } }を追加してください。 - TSエラー?
@types/graphqlと@types/nodeをインストールしてください。
結論
ハロークエリからミューテーションまで、Apollo Serverを使って堅牢なGraphQLサーバーを構築しました。JSでもTSでも、柔軟なAPIを作成する準備が整いました。実験し、サブスクリプションを追加し、Herokuにデプロイしてください。GraphQLとApollo Serverは、効率的なAPIへの切符です!
ApidogはGraphQLでのテストもサポートしていますので、ぜひ完全に無料でお試しください!

