GraphQL 入门与实践

2026-06-22 · 6 阅读 · 362字
API设计Node.js

GraphQL 入门与实践

什么是 GraphQL

GraphQL 是由 Facebook 开发的 API 查询语言和运行时。它允许客户端精确请求所需的数据,避免了 REST 中的 over-fetching 和 under-fetching 问题。

核心概念

Schema 定义

GraphQL 使用 Schema Definition Language (SDL) 定义 API 的数据类型和操作:

type User {
    id: ID!
    name: String!
    email: String!
    posts: [Post!]!
}

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

type Query {
    user(id: ID!): User
    users(page: Int, limit: Int): [User!]!
    post(id: ID!): Post
}

type Mutation {
    createUser(name: String!, email: String!): User!
    updateUser(id: ID!, name: String): User!
    deleteUser(id: ID!): Boolean!
}

Query - 查询数据

客户端精确指定所需字段:

query GetUserWithPosts {
    user(id: "1") {
        name
        email
        posts {
            title
            createdAt
        }
    }
}

Mutation - 修改数据

mutation CreateNewUser {
    createUser(name: "张三", email: "zhangsan@example.com") {
        id
        name
        email
    }
}

Subscription - 实时订阅

subscription OnNewPost {
    newPost {
        id
        title
        author {
            name
        }
    }
}

Resolver 实现

Resolver 是 schema 中每个字段的实际数据获取函数:

const resolvers = {
    Query: {
        user: async (_, { id }) => {
            return await db.users.findById(id);
        },
        users: async (_, { page = 1, limit = 10 }) => {
            return await db.users.findAll({ offset: (page - 1) * limit, limit });
        },
    },
    User: {
        posts: async (parent) => {
            return await db.posts.findAll({ where: { authorId: parent.id } });
        },
    },
};

N+1 问题

GraphQL 的嵌套查询容易引发 N+1 查询问题。使用 DataLoader 批量加载数据:

const DataLoader = require('dataloader');

const userLoader = new DataLoader(async (ids) => {
    const users = await db.users.findAllByIds(ids);
    return ids.map(id => users.find(user => user.id === id));
});

const resolvers = {
    Post: {
        author: async (post) => {
            return await userLoader.load(post.authorId);
        },
    },
};

与 REST 的对比

特性 REST GraphQL
数据获取 服务端定义返回结构 客户端精确指定
版本管理 URL 版本 (v1, v2) 通过新增字段演进
缓存 HTTP 缓存天然支持 需要额外方案
学习曲线 中等
工具生态 成熟 快速发展
适用场景 资源型 CRUD 复杂数据聚合

常用工具

  • Apollo Server:功能完整的 Node.js GraphQL 服务端
  • Apollo Client:前端 GraphQL 客户端,支持缓存和状态管理
  • GraphQL Code Generator:从 schema 自动生成 TypeScript 类型
  • GraphiQL:交互式 GraphQL IDE