Fastify + GraphQL 实战:用 Mercurius 构建高性能 API

Fastify 生态的 GraphQL 方案是 Mercurius:性能优、与 Fastify 插件体系深度集成。本文讲解 Schema 设计、类型关联、Mutation 与生产级配置。

最佳实践
应用接口与数据存储连接插画

在 Fastify 中注册 mercurius 插件即可获得 GraphQL 端点:fastify.register(mercurius, { schema, resolvers }),/graphiql 自带调试界面。Mercurius 针对 Fastify 架构优化(编译型序列化、DataLoader 集成),是 Fastify 生态 GraphQL 的标准答案。

为什么是 Mercurius

Fastify 生态有两个 GraphQL 选项:通用 Apollo Server 与专为 Fastify 设计的 Mercurius。后者的优势:直接复用 Fastify 的插件/钩子体系(认证用 Fastify 钩子而非另起炉灶)、性能优化(响应序列化走 Fastify 的编译路径)、内置 DataLoader 支持与 Subscription。

搭建与 Schema 设计

npm install fastify mercurius
const fastify = require('fastify')();
const mercurius = require('mercurius');

const schema = `
  type Post {
    id: ID!
    title: String!
    author: User!
  }

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

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

  type Mutation {
    createPost(title: String!, authorId: ID!): Post!
  }
`;

const resolvers = {
  Query: {
    posts: () => db.posts,
    user: (_, { id }) => db.users.find(u => u.id === id),
  },
  User: {
    posts: (user) => db.posts.filter(p => p.authorId === user.id),
  },
  Post: {
    author: (post) => db.users.find(u => u.id === post.authorId),
  },
  Mutation: {
    createPost: (_, { title, authorId }) => db.posts.create({ title, authorId }),
  },
};

fastify.register(mercurius, {
  schema,
  resolvers,
  graphiql: true,   // 开发期打开调试界面,生产关闭
});

fastify.listen({ port: 3000 });

Mutation:数据修改的完整姿势

mutation {
  createPost(title: "新文章", authorId: "1") {
    id
    title
    author { name }
  }
}

Mutation 与 Query 的 resolver 结构一致,区别只是语义约定(Mutation 按顺序执行,Query 并行)。Mutation 内的校验错误用抛出异常表达,Mercurius 会格式化为 errors 数组。

生产配置清单

  • graphiql: false——生产关闭交互界面;
  • 查询深度/复杂度限制:queryDepth 选项或 graphql-armor 类防护,防恶意深嵌套查询打垮服务;
  • DataLoader:resolver 里的关联加载(User.posts 这类)接 DataLoader 合并批量查询,消灭 N+1;
  • 持久化查询:只允许白名单查询 ID,公开 API 的安全标配。

验证接口上线后的延迟与错误

Fastify + GraphQL 实战完成开发验证后,可选一条包含数据库或外部调用的业务路径接入观测云。按 Node.js APM 文档确认探针初始化顺序与框架兼容性,检查请求及下游 Span 是否连续,再按文档注入日志关联字段。以路由模板或稳定的操作名聚合,避免用用户 ID、动态 URL 或完整 GraphQL 查询作为高基数标签。

接入文档:Node.js APM 接入 · 日志采集 · 日志与链路关联。

常见问题(FAQ)

Q:Mercurius 和 Apollo Server 怎么选?

Fastify 项目选 Mercurius(性能与集成优势);需要 Apollo 生态特定功能(Federation 超图、Apollo Studio 深度集成)再考虑 Apollo Server。

Q:GraphQL 如何做认证授权?

认证在 Fastify 钩子(onRequest)完成,用户注入 context;授权在 resolver 内按 context.user 判断,或用指令/中间件模式声明角色要求。

Q:Subscription(实时订阅)怎么实现?

Mercurius 内置 Subscription 支持(WebSocket 传输):Schema 声明 type Subscription,resolver 返回 PubSub 迭代器。大规模生产环境把 PubSub 换成 Redis 后端。


参考文档

本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台