mcpField
A
apollo-server

apollo-server

github.com/apollographql開発1212.9k 回インストール1 日前に更新
リポジトリ

apollo-server について

Apollo Server 5.x で GraphQL サーバーを構築するためのガイドスキルです。スキーマ、リゾルバー、リクエストコンテキスト、デプロイ方法を扱い、GraphQL API の実装に役立ちます。

主な機能

  1. 01Apollo Server 5.x の設定
  2. 02スキーマとリゾルバーの指針
  3. 03リクエスト単位のコンテキスト
  4. 04単独実行とフレームワーク連携

活用シーン

  1. 01GraphQL API のプロトタイプ作成
  2. 02リゾルバーとコンテキストの設計
  3. 03本番向けサーバー連携の選択

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/apollographql/skills --skill apollo-server

インストール後、Claude Code で/apollo-serverを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
context-and-auth.md
data-sources.md
error-handling.md
plugins.md
resolvers.md
troubleshooting.md

詳細

Apollo Server 5.x ガイド

Apollo Server は、あらゆる GraphQL スキーマで動作するオープンソースの GraphQL サーバーです。Apollo Server 5 はフレームワークに依存せず、スタンドアロンで動作するほか、Express、Fastify、サーバーレス環境と統合できます。

クイックスタート

ステップ 1:インストール
npm install @apollo/server graphql

Express との統合の場合:

npm install @apollo/server @as-integrations/express5 express graphql cors
ステップ 2:スキーマを定義する
const typeDefs = `#graphql
  type Book {
    title: String
    author: String
  }

  type Query {
    books: [Book]
  }
`;
ステップ 3:リゾルバーを作成する
const resolvers = {
  Query: {
    books: () => [
      { title: "The Great Gatsby", author: "F. Scott Fitzgerald" },
      { title: "1984", author: "George Orwell" },
    ],
  },
};
ステップ 4:サーバーを起動する

スタンドアロン(プロトタイピングにおすすめ):

スタンドアロンサーバーはプロトタイピングに最適ですが、本番サービスでは、Apollo Server を Express、Koa、Fastify などのより高機能なウェブフレームワークと統合することをおすすめします。後からスタンドアロンサーバーをウェブフレームワークに切り替えるのは簡単です。

import { ApolloServer } from "@apollo/server";
import { startStandaloneServer } from "@apollo/server/standalone";

const server = new ApolloServer({ typeDefs, resolvers });

const { url } = await startStandaloneServer(server, {
  listen: { port: 4000 },
});

console.log(`Server ready at ${url}`);

Express:

import { ApolloServer } from "@apollo/server";
import { expressMiddleware } from "@as-integrations/express5";
import { ApolloServerPluginDrainHttpServer } from "@apollo/server/plugin/drainHttpServer";
import express from "express";
import http from "http";
import cors from "cors";

const app = express();
const httpServer = http.createServer(app);

const server = new ApolloServer({
  typeDefs,
  resolvers,
  plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
});

await server.start();

app.use(
  "/graphql",
  cors(),
  express.json(),
  expressMiddleware(server, {
    context: async ({ req }) => ({ token: req.headers.authorization }),
  }),
);

await new Promise<void>((resolve) => httpServer.listen({ port: 4000 }, resolve));
console.log("Server ready at http://localhost:4000/graphql");

スキーマ定義

スカラー型
  • Int - 32 ビット整数
  • Float - 倍精度浮動小数点数
  • String - UTF-8 文字列
  • Boolean - true/false
  • ID - 一意の識別子(String としてシリアライズされます)
型定義
type User {
  id: ID!
  name: String!
  email: String
  posts: [Post!]!
}

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

input CreatePostInput {
  title: String!
  content: String
}

type Query {
  user(id: ID!): User
  users: [User!]!
}

type Mutation {
  createPost(input: CreatePostInput!): Post!
}
列挙型とインターフェース
enum Status {
  DRAFT
  PUBLISHED
  ARCHIVED
}

interface Node {
  id: ID!
}

type Article implements Node {
  id: ID!
  title: String!
}

リゾルバーの概要

リゾルバーのシグネチャは次のとおりです:(parent, args, contextValue, info)

  • parent:親リゾルバーの結果(ルートリゾルバーでは undefined が渡されます)
  • args:フィールドに渡される引数
  • contextValue:共有コンテキストオブジェクト(認証、dataSources など)
  • info:フィールド固有の情報とスキーマの詳細(通常は使用しません)
const resolvers = {
  Query: {
    user: async (_, { id }, { dataSources }) => {
      return dataSources.usersAPI.getUser(id);
    },
  },
  User: {
    posts: async (parent, _, { dataSources }) => {
      return dataSources.postsAPI.getPostsByAuthor(parent.id);
    },
  },
  Mutation: {
    createPost: async (_, { input }, { dataSources, user }) => {
      if (!user) throw new GraphQLError("Not authenticated");
      return dataSources.postsAPI.create({ ...input, authorId: user.id });
    },
  },
};

コンテキストの設定

コンテキストはリクエストごとに作成され、すべてのリゾルバーに渡されます。

interface MyContext {
  token?: string;
  user?: User;
  dataSources: {
    usersAPI: UsersDataSource;
    postsAPI: PostsDataSource;
  };
}

const server = new ApolloServer<MyContext>({
  typeDefs,
  resolvers,
});

// Standalone
const { url } = await startStandaloneServer(server, {
  context: async ({ req }) => ({
    token: req.headers.authorization || "",
    user: await getUser(req.headers.authorization || ""),
    dataSources: {
      usersAPI: new UsersDataSource(),
      postsAPI: new PostsDataSource(),
    },
  }),
});

// Express middleware
expressMiddleware(server, {
  context: async ({ req, res }) => ({
    token: req.headers.authorization,
    user: await getUser(req.headers.authorization),
    dataSources: {
      usersAPI: new UsersDataSource(),
      postsAPI: new PostsDataSource(),
    },
  }),
});

参照ファイル

トピック別の詳細なドキュメント:

重要なルール

スキーマ設計
  • 常に値があるフィールドには !(非 null)を使用します
  • ミューテーションではインライン引数より入力型を優先します
  • 多態的な型にはインターフェースを使用します
  • ドキュメント用にスキーマの説明を残します
リゾルバーのベストプラクティス
  • リゾルバーは薄く保ち、サービス/データソースに処理を委任します
  • エラーは必ず明示的に処理します
  • 関連するクエリのバッチ処理には DataLoader を使用します
  • 可能な場合は部分データを返します(GraphQL の強みです)
パフォーマンス
  • 大きなレスポンスには @defer と @stream を使用します
  • DataLoader を実装して N+1 クエリを解消します
  • 本番環境では永続化クエリを検討します
  • 適切な場合はキャッシュヘッダーと CDN を使用します

基本ルール

  • 必ず Apollo Server 5.x のパターンを使用します(v4 以前のものは使用しません)
  • 必ず TypeScript のジェネリクスでコンテキストに型を指定します
  • エラーには必ず graphql パッケージの GraphQLError を使用します
  • 本番環境のエラーではスタックトレースを決して公開しません
  • プロトタイピングに限り、startStandaloneServer を優先します
  • 本番アプリでは Express、Koa、Fastify、Next などのサーバーフレームワークとの統合を使用します
  • コンテキストで認証を、リゾルバーで認可を実装します

コメント