apollo-server

Panduan lengkap untuk membangun server GraphQL dengan Apollo Server 5.x di berbagai framework. Mencakup definisi skema, resolver, pengaturan konteks, dan penanganan kesalahan dengan dukungan TypeScript. Mendukung mode mandiri untuk pembuatan prototipe dan integrasi dengan Express, Fastify, Koa, serta lingkungan serverless. Termasuk pola resolver, autentikasi/otorisasi, plugin, DataLoader untuk pencegahan N+1, dan teknik optimasi kinerja. Menyediakan dokumentasi referensi untuk sumber data, kesalahan...

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

Lebih banyak skill dari apollographql

apollo-federation
apollographql
Apollo Federation memungkinkan penggabungan beberapa API GraphQL (subgraf) menjadi satu supergraf yang terpadu.
apollo-ios
apollographql
Apollo iOS adalah klien GraphQL yang diketik secara kuat untuk platform Apple. Ia menghasilkan tipe Swift dari operasi dan skema GraphQL Anda, serta menyertakan klien async/await, cache yang dinormalisasi (berbasis memori atau SQLite), transport HTTP berbasis interceptor yang dapat dipasang untuk menangani kueri, mutasi, dan langganan multipart, serta transport WebSocket opsional (graphql-transport-ws) yang dapat membawa jenis operasi apa pun.
apollo-router
apollographql
Apollo Router adalah router graf berkinerja tinggi yang ditulis dalam Rust untuk menjalankan supergraf Apollo Federation 2. Router ini berada di depan subgraf Anda dan menangani perencanaan kueri, eksekusi, serta komposisi respons.
apollo-router-plugin-creator
apollographql
Buat plugin Rust asli untuk Apollo Router.
graphql-operations
apollographql
Panduan praktik terbaik untuk menulis operasi GraphQL yang efisien dan aman tipe serta mengaturnya dengan fragmen. Mencakup kueri, mutasi, langganan, dan fragmen dengan konvensi penamaan, sintaks variabel, dan penggunaan direktif. Menekankan prinsip inti: hanya meminta bidang yang diperlukan, beri nama semua operasi, gunakan variabel alih-alih nilai hardcoded, dan sertakan bidang id untuk cacheability. Merekomendasikan penempatan fragmen bersama komponen dan menggunakan direktif @include / @skip untuk bidang kondisional...
graphql-schema
apollographql
Panduan praktik terbaik industri untuk merancang skema GraphQL yang intuitif, berperforma tinggi, dan mudah dipelihara. Mencakup prinsip desain inti termasuk organisasi tipe yang berpusat pada klien, pola nullability eksplisit, dan strategi evolusi yang kompatibel ke belakang. Menyediakan dokumentasi referensi tentang tipe, konvensi penamaan, pagination berbasis kursor, pemodelan kesalahan, dan pertimbangan keamanan. Mencakup pola praktis untuk antarmuka, union, tipe input, mutasi, dan strategi ID dengan contoh kode...
rover
apollographql
CLI Apollo Rover untuk mengelola skema GraphQL, federasi, dan pengembangan supergraph lokal. Publikasikan, ambil, dan validasi skema subgraph; buat supergraph terfederasi secara lokal atau melalui GraphOS. Termasuk pemeriksaan skema (validasi pra-deploy), linting, dan introspeksi dari server yang berjalan. Perintah rover dev memulai Router lokal dengan komposisi skema otomatis untuk alur kerja pengembangan. Mendukung pola CI/CD dengan validasi periksa-sebelum-publikasi dan output JSON untuk skrip. Memerlukan...
rust-best-practices
apollographql
Standar pengkodean Rust idiomatik berdasarkan buku pedoman praktik terbaik Apollo GraphQL. Mencakup sembilan area inti: gaya dan idiom pengkodean, linting clippy, optimasi kinerja, penanganan error, pola pengujian, generik dan dispatch, pola state tipe, dokumentasi, dan keamanan pointer. Menekankan peminjaman daripada kloning, penanganan error berbasis Result dengan thiserror/anyhow, dan profiling kinerja dengan build rilis. Termasuk panduan referensi cepat tentang pola kepemilikan, penghindaran panic,...