apollo-server vs express-graphql
Node.js GraphQL 服务器实现方案对比
apollo-serverexpress-graphql類似套件:

Node.js GraphQL 服务器实现方案对比

apollo-server 和 express-graphql 都是用于在 Node.js 环境中构建 GraphQL 服务器的库,但它们的定位和维护状态截然不同。apollo-server 是一个功能完整的框架,提供内置的缓存、插件系统和联合网关支持,适合复杂的企业级应用。express-graphql 是一个轻量级的 Express 中间件,旨在快速将 GraphQL 挂载到现有 Express 应用中,但目前已停止维护。

npm下載趨勢

3 年

GitHub Stars 排名

統計詳情

套件
下載數
Stars
大小
Issues
發布時間
許可
apollo-server013,95826.6 kB903 年前MIT
express-graphql06,249-546 年前MIT

Apollo Server vs Express-GraphQL:架构、维护状态与工程实践

在 Node.js 生态中,apollo-server 和 express-graphql 都曾是构建 GraphQL API 的主流选择。它们都解决了将 GraphQL schema 暴露为 HTTP 端点的问题,但在架构设计、扩展能力和维护状态上存在巨大差异。对于正在做技术选型的开发者来说,理解这些差异至关重要 — 尤其是考虑到它们当前的维护状态。

⚠️ 维护状态:弃用警告与迁移路径

这是选择这两个包之前必须了解的最重要信息。两者在 npm 上均带有弃用或维护模式警告。

apollo-server 指的是 Apollo Server v3。官方已将其置于维护模式,推荐使用 v4 版本(包名为 @apollo/server)。

// apollo-server (v3 - 维护模式)
const { ApolloServer } = require('apollo-server');
// 新项目应使用:const { ApolloServer } = require('@apollo/server');

express-graphql 已由 GraphQL 基金会正式弃用,仓库已归档,不再接受新功能或安全修复。

// express-graphql (已弃用)
const graphqlHTTP = require('express-graphql');
// 官方建议迁移至:@apollo/server 或 graphql-http

💡 建议:如果是新项目,请直接使用 @apollo/server。如果是旧项目,请制定迁移计划,避免技术债务累积。

🚀 集成方式:独立服务器 vs Express 中间件

两者的集成模式反映了不同的设计哲学。apollo-server 倾向于作为独立服务器运行,而 express-graphql 设计为 Express 应用的一部分。

apollo-server 默认启动自己的 HTTP 服务器,虽然也可以集成到 Express 中,但推荐 standalone 模式。

// apollo-server: 独立启动
const { ApolloServer } = require('apollo-server');
const server = new ApolloServer({ typeDefs, resolvers });

server.listen().then(({ url }) => {
  console.log(`Server ready at ${url}`);
});

express-graphql 必须依附于 Express 应用,作为中间件挂载到特定路由。

// express-graphql: 中间件模式
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const app = express();

app.use('/graphql', graphqlHTTP({
  schema: makeExecutableSchema({ typeDefs, resolvers }),
  graphiql: true
}));

app.listen(4000);

📥 上下文管理:Context 函数 vs 请求对象

在 GraphQL 解析过程中,context 用于传递认证信息、数据库连接等共享数据。两者的处理方式不同。

apollo-server 提供专门的 context 配置项,支持异步初始化,适合处理复杂的认证逻辑。

// apollo-server: 专用 Context 配置
const server = new ApolloServer({
  typeDefs,
  resolvers,
  context: async ({ req }) => {
    const token = req.headers.authorization;
    const user = await validateToken(token);
    return { user };
  }
});

express-graphql 直接接收一个 context 对象或函数,但功能较为基础,通常直接复用 Express 的 req 对象。

// express-graphql: 简单 Context 传递
app.use('/graphql', graphqlHTTP({
  schema,
  context: { req }, // 直接传递 request 对象
  graphiql: true
}));

🛡️ 错误处理:格式化输出 vs 原始抛出

GraphQL 的错误处理直接影响前端调试体验。apollo-server 提供了更强大的错误格式化能力。

apollo-server 内置 formatError 钩子,可以隐藏内部堆栈信息,统一错误结构。

// apollo-server: 自定义错误格式
const server = new ApolloServer({
  typeDefs,
  resolvers,
  formatError: (error) => {
    return {
      message: error.message,
      code: error.extensions?.code || 'INTERNAL_ERROR'
    };
  }
});

express-graphql 也支持 customFormatErrorFn,但配置选项较少,且不再更新以适应新标准。

// express-graphql: 基础错误格式化
app.use('/graphql', graphqlHTTP({
  schema,
  customFormatErrorFn: (error) => ({
    message: error.message,
    locations: error.locations
  })
}));

🔌 扩展能力:插件系统 vs 中间件链

当需要添加日志、缓存或追踪功能时,扩展性变得关键。

apollo-server 拥有成熟的插件系统(Plugins),可以监听请求生命周期各个阶段。

// apollo-server: 插件系统
const server = new ApolloServer({
  typeDefs,
  resolvers,
  plugins: [
    {
      requestDidStart: () => ({
        willSendResponse: () => console.log('Response sent')
      })
    }
  ]
});

express-graphql 依赖 Express 的中间件链,需要在路由前后手动添加逻辑,缺乏 GraphQL 特定的生命周期钩子。

// express-graphql: 依赖 Express 中间件
app.use('/graphql', (req, res, next) => {
  console.log('Request received');
  next();
}, graphqlHTTP({ schema }));

🤝 相似之处:共同的基础

尽管存在差异,这两个库在核心功能上有很多重叠,因为它们都基于 graphql-js。

1. 📜 Schema 定义方式相同

  • 都使用 GraphQL Schema Definition Language (SDL)。
  • 解析器(Resolvers)结构基本一致。
// 两者通用的 Schema 定义
const typeDefs = `#graphql
  type Query {
    hello: String
  }
`;
const resolvers = { Query: { hello: () => 'World' } };

2. 🌐 支持 GraphiQL 调试界面

  • 都内置了 GraphiQL 界面,方便开发者测试查询。
  • 可通过配置开关启用或禁用。
// apollo-server: 默认启用 (开发环境)
// express-graphql: 需显式配置
graphqlHTTP({ schema, graphiql: true })

3. ✅ 支持 HTTP 协议传输

  • 都通过 HTTP POST 请求接收 GraphQL 查询。
  • 都支持标准的 GraphQL 响应格式。
// 两者通用的请求结构
// POST /graphql
// Body: { "query": "{ hello }" }

📊 总结:关键差异对比

特性apollo-serverexpress-graphql
维护状态⚠️ 维护模式 (推荐迁至 v4)❌ 已弃用 (不再更新)
集成模式🚀 独立服务器为主🧩 Express 中间件
上下文管理🛠️ 异步 Context 函数📦 简单对象传递
错误处理🛡️ 强大格式化钩子📝 基础格式化支持
扩展能力🔌 专用插件系统🔗 依赖 Express 中间件
适用场景企业级、复杂架构旧项目维护、简单脚本

💡 最终建议

apollo-server 就像是一个功能齐全的工程车 🚛 — 虽然 v3 版本已进入维护期,但其架构设计依然 robust,适合需要稳定性能监控和复杂扩展的场景。迁移到 @apollo/server 后,它能继续支撑大型应用。

express-graphql 就像是一个简易工具包 🧰 — 曾经非常流行,但现在已生锈。它的简单性在早期是优势,但现在成了安全隐患。除非你被锁定在无法修改的旧系统中,否则不应再使用它。

核心结论:对于现代 Node.js GraphQL 开发,请跳过这两个包的直接选择,转而采用 @apollo/server。它继承了 apollo-server 的优点,修复了架构问题,并保持了活跃维护。技术选型不仅要看功能,更要看未来 — 选择一个活跃的生态比选择一个简单的库更重要。

如何選擇: apollo-server vs express-graphql

  • apollo-server:

    仅建议在维护现有的 Apollo Server v3 项目时使用,新项目应直接采用 @apollo/server。如果你需要内置的性能监控、复杂的插件系统或 Apollo 联邦架构,这是更合适的选择。虽然包名已标记为维护模式,但其生态迁移路径清晰,适合长期演进。

  • express-graphql:

    不建议在任何新项目中选择此包,因为它已正式弃用且不再接收安全更新。仅在无法重构的遗留系统中暂时保留,且应尽快计划迁移至 @apollo/server 或 graphql-http。它的简单性不再足以抵消安全风险和功能缺失。

apollo-server 的 README

Apollo Server

A TypeScript GraphQL Server for Express, Koa, Hapi, Lambda, and more.

npm version Build Status Join the community forum Read CHANGELOG

Apollo Server is a community-maintained open-source GraphQL server. It works with many Node.js HTTP server frameworks, or can run on its own with a built-in Express server. Apollo Server works with any GraphQL schema built with GraphQL.js--or define a schema's type definitions using schema definition language (SDL).

Read the documentation for information on getting started and many other use cases and follow the CHANGELOG for updates.

Principles

Apollo Server is built with the following principles in mind:

  • By the community, for the community: Its development is driven by the needs of developers.
  • Simplicity: By keeping things simple, it is more secure and easier to implement and contribute.
  • Performance: It is well-tested and production-ready.

Anyone is welcome to contribute to Apollo Server, just read CONTRIBUTING.md, take a look at the roadmap and make your first PR!

Getting started

To get started with Apollo Server:

  • Install with npm install apollo-server-<integration> graphql
  • Write a GraphQL schema
  • Use one of the following snippets

There are two ways to install Apollo Server:

  • Standalone: For applications that do not require an existing web framework, use the apollo-server package.
  • Integrations: For applications with a web framework (e.g. express, koa, hapi, etc.), use the appropriate Apollo Server integration package.

For more info, please refer to the Apollo Server docs.

Installation: Standalone

In a new project, install the apollo-server and graphql dependencies using:

npm install apollo-server graphql

Then, create an index.js which defines the schema and its functionality (i.e. resolvers):

const { ApolloServer, gql } = require('apollo-server');

// The GraphQL schema
const typeDefs = gql`
  type Query {
    "A simple type for getting started!"
    hello: String
  }
`;

// A map of functions which return data for the schema.
const resolvers = {
  Query: {
    hello: () => 'world',
  },
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`);
});

Due to its human-readability, we recommend using schema-definition language (SDL) to define a GraphQL schema--a GraphQLSchema object from graphql-js can also be specified instead of typeDefs and resolvers using the schema property:

const server = new ApolloServer({
  schema: ...
});

Finally, start the server using node index.js and go to the URL returned on the console.

For more details, check out the Apollo Server Getting Started guide and the fullstack tutorial.

For questions, the Apollo community forum is a great place to get help.

Installation: Integrations

While the standalone installation above can be used without making a decision about which web framework to use, the Apollo Server integration packages are paired with specific web frameworks (e.g. Express, Koa, hapi).

The following web frameworks have Apollo Server integrations, and each of these linked integrations has its own installation instructions and examples on its package README.md:

Context

A request context is available for each request. When context is defined as a function, it will be called on each request and will receive an object containing a req property, which represents the request itself.

By returning an object from the context function, it will be available as the third positional parameter of the resolvers:

new ApolloServer({
  typeDefs,
  resolvers: {
    Query: {
      books: (parent, args, context, info) => {
        console.log(context.myProperty); // Will be `true`!
        return books;
      },
    }
  },
  context: async ({ req }) => {
    return {
      myProperty: true
    };
  },
})

Documentation

The Apollo Server documentation contains additional details on how to get started with GraphQL and Apollo Server.

The raw Markdown source of the documentation is available within the docs/ directory of this monorepo--to contribute, please use the Edit on GitHub buttons at the bottom of each page.

Development

If you wish to develop or contribute to Apollo Server, we suggest the following:

  • Fork this repository

  • Install Direnv (a tool that automatically sets up environment variables in project directories) or nvm. We use nvm to ensure we're running the expected version of Node (and we use Direnv to install and run nvm automatically).

  • Install the Apollo Server project on your computer

git clone https://github.com/[your-user]/apollo-server
cd apollo-server
direnv allow  # sets up nvm for you; if you installed nvm yourself, try `nvm install` instead
  • Build and test
npm install
npm test
  • To run individual test files, run npm run pretest && npx jest packages/apollo-server-foo/src/__tests__/bar.test.ts. Note that you do need to re-compile TypeScript before each time you run a test, or changes across packages may not be picked up. Instead of running npm run pretest from scratch before each test run, you can also run tsc --build tsconfig.json --watch in another shell, or use the VSCode Run Build Task to run that for you.

Community

Are you stuck? Want to contribute? Come visit us in the Apollo community forum!

Maintainers

Who is Apollo?

Apollo builds open-source software and a graph platform to unify GraphQL across your apps and services. We help you ship faster with:

  • Apollo Studio – A free, end-to-end platform for managing your GraphQL lifecycle. Track your GraphQL schemas in a hosted registry to create a source of truth for everything in your graph. Studio provides an IDE (Apollo Explorer) so you can explore data, collaborate on queries, observe usage, and safely make schema changes.
  • Apollo Federation – The industry-standard open architecture for building a distributed graph. Use Apollo’s gateway to compose a unified graph from multiple subgraphs, determine a query plan, and route requests across your services.
  • Apollo Client – The most popular GraphQL client for the web. Apollo also builds and maintains Apollo iOS and Apollo Android.
  • Apollo Server – A production-ready JavaScript GraphQL server that connects to any microservice, API, or database. Compatible with all popular JavaScript frameworks and deployable in serverless environments.

Learn how to build with Apollo

Check out the Odyssey learning platform, the perfect place to start your GraphQL journey with videos and interactive code challenges. Join the Apollo Community to interact with and get technical help from the GraphQL community.