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 后端。
参考文档
本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。