apollo-server、express-graphql 和 graphql-tools 都是用于构建和管理 GraphQL API 的 JavaScript 工具,但它们在职责、使用场景和架构定位上存在显著差异。apollo-server 是一个功能完整的 GraphQL 服务器框架,支持多种 HTTP 框架并内置开发工具;express-graphql 是一个轻量级中间件,专为 Express 应用提供 GraphQL 支持;而 graphql-tools 并非服务器,而是一组用于构建 GraphQL schema 和执行逻辑的实用函数,常与其他服务器搭配使用。
在构建现代前端应用时,GraphQL 已成为许多团队替代 REST 的首选数据查询语言。然而,如何在 Node.js 环境中搭建 GraphQL 服务,开发者面临多个选择:apollo-server、express-graphql 和 graphql-tools。它们看似相似,实则定位迥异 —— 有的是完整服务器,有的是中间件,有的则是底层工具库。本文将从工程实践角度,深入剖析三者的本质区别与适用场景。
理解这三者的首要前提是认清它们的根本角色:
apollo-server 是一个独立的 GraphQL 服务器框架,可直接处理 HTTP 请求并返回 GraphQL 响应,支持 Express、Koa、Fastify 等多种底层 HTTP 框架,也可独立运行。express-graphql 是一个Express 专用中间件,必须嵌入 Express 应用中使用,无法脱离 Express 环境。graphql-tools 不是服务器,而是一组用于构建和操作 GraphQL schema 的工具函数,需配合其他 GraphQL 执行引擎(如 graphql-js)和服务器使用。⚠️ 注意:根据 npm 官方页面和 GitHub 仓库信息,
express-graphql已被标记为不再积极维护,官方建议新项目使用apollo-server或其他现代替代方案。
apollo-serverapollo-server 提供了最简洁的启动方式,无需手动配置 HTTP 服务器:
// apollo-server 示例
import { ApolloServer } from 'apollo-server';
import { gql } from 'apollo-server';
const typeDefs = gql`
type Query {
hello: String
}
`;
const resolvers = {
Query: {
hello: () => 'Hello from Apollo Server!'
}
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
它也支持与 Express 集成:
// 与 Express 集成
import express from 'express';
import { ApolloServer } from 'apollo-server-express';
const app = express();
const server = new ApolloServer({ typeDefs, resolvers });
await server.start();
server.applyMiddleware({ app });
app.listen(4000, () => {
console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`);
});
express-graphqlexpress-graphql 必须作为 Express 中间件挂载:
// express-graphql 示例
import express from 'express';
import { graphqlHTTP } from 'express-graphql';
import { buildSchema } from 'graphql';
const schema = buildSchema(`
type Query {
hello: String
}
`);
const root = {
hello: () => 'Hello from express-graphql!'
};
const app = express();
app.use('/graphql', graphqlHTTP({
schema,
rootValue: root,
graphiql: true // 启用 GraphiQL
}));
app.listen(4000);
graphql-toolsgraphql-tools 本身不能启动服务,需配合其他服务器。常见用法是与 apollo-server 结合:
// graphql-tools + apollo-server
import { makeExecutableSchema } from '@graphql-tools/schema';
import { ApolloServer } from 'apollo-server';
const typeDefs = `
type Query {
hello: String
}
`;
const resolvers = {
Query: {
hello: () => 'Hello from graphql-tools!'
}
};
const schema = makeExecutableSchema({ typeDefs, resolvers });
const server = new ApolloServer({ schema });
server.listen();
apollo-serverapollo-server 内部使用 graphql-tools(旧版本)或自研 schema 构建逻辑(新版本),支持直接传入 typeDefs 和 resolvers 对象,也接受预构建的 GraphQLSchema 实例。
// apollo-server 接受多种 schema 输入
new ApolloServer({
typeDefs: gql`...`,
resolvers: { ... }
});
// 或
new ApolloServer({ schema: myPrebuiltSchema });
express-graphql仅支持传入 GraphQLSchema 实例,通常需配合 graphql-js 的 buildSchema 或手动构造:
// express-graphql 要求 schema 是 GraphQLSchema 类型
const schema = buildSchema(`type Query { hello: String }`);
graphqlHTTP({ schema, rootValue: root });
graphql-tools这是其核心优势所在。graphql-tools 提供了强大的 schema 构建能力,包括:
makeExecutableSchemamergeSchemasstitchSchemasaddMocksToSchema// 使用 graphql-tools 合并多个 schema
import { mergeSchemas } from '@graphql-tools/merge';
const userSchema = makeExecutableSchema({ ... });
const postSchema = makeExecutableSchema({ ... });
const combinedSchema = mergeSchemas({
schemas: [userSchema, postSchema]
});
apollo-server:内置 Apollo Studio 集成、性能追踪、错误格式化、插件系统、订阅(Subscriptions)支持。express-graphql:仅提供基础的 GraphiQL 支持,无高级调试或监控功能。graphql-tools:不涉及运行时功能,但提供 mockServer 等开发辅助工具。apollo-server 允许自定义错误格式:
const server = new ApolloServer({
formatError: (err) => ({
message: err.message,
code: err.extensions?.code || 'INTERNAL_ERROR'
})
});
而 express-graphql 的错误处理较为原始,需自行封装中间件。
apollo-server 原生支持 WebSocket 订阅:
const server = new ApolloServer({
typeDefs,
resolvers,
subscriptions: {
path: '/subscriptions'
}
});
express-graphql 不支持订阅,需额外集成 subscriptions-transport-ws 等库,且配置复杂。
在实际项目中,这三者常以组合方式出现:
apollo-server + graphql-tools(利用后者构建复杂 schema,前者提供服务)express-graphql(仅用于简单 Express 应用,新项目应避免)graphql-tools 的 stitchSchemas + apollo-server(实现 GraphQL 网关)“This package is no longer actively maintained. We recommend using Apollo Server instead.”
这意味着:
graphql-js 的兼容性无法保证因此,新项目绝不应选择 express-graphql,除非你正在维护一个无法升级的旧系统。
| 特性 | apollo-server | express-graphql | graphql-tools |
|---|---|---|---|
| 类型 | 完整 GraphQL 服务器 | Express 中间件 | Schema 构建工具库 |
| HTTP 框架支持 | 多种(Express/Koa/Fastify/独立) | 仅 Express | 无(不处理 HTTP) |
| Schema 构建 | 支持 SDL 和对象 | 仅 GraphQLSchema 实例 | 强大(合并、委托、Mock) |
| 订阅支持 | ✅ 原生支持 | ❌ 不支持 | ❌(需配合服务器) |
| 维护状态 | ✅ 积极维护 | ❌ 已弃用 | ✅ 积极维护 |
| 适用场景 | 新项目首选 | 旧系统维护 | 复杂 schema 构建 |
apollo-server,它提供了最完整的开箱即用体验。apollo-server 基础上引入 graphql-tools,利用其 mergeSchemas 或 stitchSchemas 能力。express-graphql:计划迁移至 apollo-server,避免长期技术债务。记住:graphql-tools 不是服务器,而是让你更轻松地“造 schema”;而 apollo-server 是那个“跑 schema”的引擎。两者配合,才是现代 GraphQL 服务的最佳实践。
选择 graphql-tools 当你需要灵活地构建 schema(如通过 SDL 字符串)、合并多个 schema、模拟数据或实现 schema 委托(schema stitching)等高级模式,通常与 apollo-server 或其他 GraphQL 服务器配合使用。它不提供 HTTP 服务层,而是专注于 schema 构建和执行逻辑。
选择 express-graphql 仅当你已有基于 Express 的简单应用,且只需要最基础的 GraphQL 路由支持,同时希望避免引入额外依赖。注意:该包已不再积极维护,新项目应优先考虑其他方案。
选择 apollo-server 如果你需要一个开箱即用、功能全面的 GraphQL 服务器,它提供内置的 Apollo Studio 集成、订阅支持、插件系统和错误格式化等高级功能。适合中大型项目或需要快速搭建生产级 GraphQL 服务的团队。
ERROR: No README data found!