apollo-server

Hướng dẫn hoàn chỉnh để xây dựng máy chủ GraphQL với Apollo Server 5.x trên nhiều framework. Bao gồm định nghĩa schema, resolver, thiết lập context và xử lý lỗi với hỗ trợ TypeScript. Hỗ trợ chế độ standalone để tạo nguyên mẫu và tích hợp với Express, Fastify, Koa cùng môi trường serverless. Bao gồm các mẫu resolver, xác thực/phân quyền, plugin, DataLoader để ngăn chặn N+1 và các kỹ thuật tối ưu hiệu suất. Cung cấp tài liệu tham khảo cho nguồn dữ liệu, lỗi...

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

Apollo Server 5.x Guide

Apollo Server is an open-source GraphQL server that works with any GraphQL schema. Apollo Server 5 is framework-agnostic and runs standalone or integrates with Express, Fastify, and serverless environments.

Quick Start

Step 1: Install

npm install @apollo/server graphql

For Express integration:

npm install @apollo/server @as-integrations/express5 express graphql cors

Step 2: Define Schema

const typeDefs = `#graphql
  type Book {
    title: String
    author: String
  }

  type Query {
    books: [Book]
  }
`;

Step 3: Write Resolvers

const resolvers = {
  Query: {
    books: () => [
      { title: "The Great Gatsby", author: "F. Scott Fitzgerald" },
      { title: "1984", author: "George Orwell" },
    ],
  },
};

Step 4: Start Server

Standalone (Recommended for prototyping):

The standalone server is great for prototyping, but for production services, we recommend integrating Apollo Server with a more fully-featured web framework such as Express, Koa, or Fastify. Swapping from the standalone server to a web framework later is straightforward.

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");

Schema Definition

Scalar Types

  • Int - 32-bit integer
  • Float - Double-precision floating-point
  • String - UTF-8 string
  • Boolean - true/false
  • ID - Unique identifier (serialized as String)

Type Definitions

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!
}

Enums and Interfaces

enum Status {
  DRAFT
  PUBLISHED
  ARCHIVED
}

interface Node {
  id: ID!
}

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

Resolvers Overview

Resolvers follow the signature: (parent, args, contextValue, info)

  • parent: Result from parent resolver (root resolvers receive undefined)
  • args: Arguments passed to the field
  • contextValue: Shared context object (auth, dataSources, etc.)
  • info: Field-specific info and schema details (rarely used)
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 });
    },
  },
};

Context Setup

Context is created per-request and passed to all resolvers.

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(),
    },
  }),
});

Reference Files

Detailed documentation for specific topics:

Key Rules

Schema Design

  • Use ! (non-null) for fields that always have values
  • Prefer input types for mutations over inline arguments
  • Use interfaces for polymorphic types
  • Keep schema descriptions for documentation

Resolver Best Practices

  • Keep resolvers thin - delegate to services/data sources
  • Always handle errors explicitly
  • Use DataLoader for batching related queries
  • Return partial data when possible (GraphQL's strength)

Performance

  • Use @defer and @stream for large responses
  • Implement DataLoader to solve N+1 queries
  • Consider persisted queries for production
  • Use caching headers and CDN where appropriate

Ground Rules

  • ALWAYS use Apollo Server 5.x patterns (not v4 or earlier)
  • ALWAYS type your context with TypeScript generics
  • ALWAYS use GraphQLError from graphql package for errors
  • NEVER expose stack traces in production errors
  • PREFER startStandaloneServer for prototyping only
  • USE an integration with a server framework like Express, Koa, Fastify, Next, etc. for production apps
  • IMPLEMENT authentication in context, authorization in resolvers

Thêm skills từ apollographql

apollo-client
apollographql
Apollo Client là một thư viện quản lý trạng thái toàn diện cho JavaScript, cho phép bạn quản lý cả dữ liệu cục bộ và từ xa với GraphQL. Phiên bản 4.x mang lại cải tiến về bộ nhớ đệm, hỗ trợ TypeScript tốt hơn và tương thích với React 19.
official
apollo-client
apollographql
Hướng dẫn toàn diện để xây dựng ứng dụng React với Apollo Client 4.x, bao gồm truy vấn, thay đổi dữ liệu, bộ nhớ đệm và quản lý trạng thái. Hỗ trợ nhiều framework và thiết lập React: ứng dụng phía client (Vite, CRA), Next.js App Router với React Server Components, React Router 7 với streaming SSR, và TanStack Start. Bao gồm các hooks cho truy vấn (useQuery, useLazyQuery), thay đổi dữ liệu (useMutation) và các mẫu dựa trên Suspense (useSuspenseQuery, useBackgroundQuery) cho React 18+ và 19 hiện đại...
official
apollo-connectors
apollographql
Tích hợp REST API vào siêu đồ thị GraphQL bằng cách sử dụng các chỉ thị @source và @connect. Cung cấp quy trình 5 bước có cấu trúc: nghiên cứu cấu trúc API, triển khai lược đồ với các chỉ thị, xác thực qua rover supergraph compose, thực thi các kết nối và kiểm tra phạm vi bao phủ. Hỗ trợ cấu hình yêu cầu bao gồm tiêu đề, tải trọng nội dung, xử lý hàng loạt cho các mẫu N+1 và tiêm biến môi trường qua $env. Xử lý ánh xạ phản hồi với lựa chọn trường, bí danh, lựa chọn phụ cho dữ liệu lồng nhau và thực thể...
official
apollo-federation
apollographql
Apollo Federation cho phép kết hợp nhiều API GraphQL (subgraph) thành một siêu đồ thị thống nhất.
official
apollo-ios
apollographql
Apollo iOS là một trình khách GraphQL có kiểu mạnh dành cho các nền tảng Apple. Nó tạo ra các kiểu Swift từ các thao tác và lược đồ GraphQL của bạn, đồng thời cung cấp một trình khách async/await, bộ nhớ đệm chuẩn hóa (trong bộ nhớ hoặc dùng SQLite), một lớp truyền tải HTTP dựa trên interceptor có thể cắm thêm để xử lý các truy vấn, biến đổi và đăng ký đa phần, cùng với một lớp truyền tải WebSocket tùy chọn (graphql-transport-ws) có thể mang bất kỳ loại thao tác nào.
official
apollo-kotlin
apollographql
Apollo Kotlin là một máy khách GraphQL được định kiểu mạnh, tạo ra các mô hình Kotlin từ các thao tác và lược đồ GraphQL của bạn, có thể được sử dụng trong các dự án Android, JVM và Kotlin Multiplatform.
official
apollo-mcp-server
apollographql
Kết nối các tác nhân AI với API GraphQL thông qua Giao thức Ngữ cảnh Mô hình (Model Context Protocol) với các công cụ nội quan và thao tác tích hợp. Hiển thị các thao tác GraphQL dưới dạng công cụ MCP; hỗ trợ ba nguồn thao tác: tệp cục bộ, bộ sưu tập GraphOS Studio và tệp kê khai truy vấn đã lưu. Cung cấp bốn công cụ nội quan (introspect, search, validate, execute) để khám phá lược đồ và kiểm tra truy vấn tùy chỉnh; chế độ thu nhỏ giảm mức sử dụng token với ký hiệu nhỏ gọn. Xác thực có thể cấu hình qua tiêu đề tĩnh,...
official
apollo-router
apollographql
Apollo Router là một bộ định tuyến đồ thị hiệu suất cao được viết bằng Rust để chạy các siêu đồ thị Apollo Federation 2. Nó nằm phía trước các đồ thị con của bạn và xử lý việc lập kế hoạch truy vấn, thực thi và tổng hợp phản hồi.
official