使用 JavaScript 的 GraphQL API 入门
GraphQL 是一种由 Facebook 开发的 API 查询语言。与 REST 不同,REST 的每个端点返回固定的数据结构,而 GraphQL 允许客户端只请求所需的字段。这减少了传输的数据量,并简化了复杂应用程序的开发。
在本教程中,我们将使用 Apollo Server 在 Node.js 上创建一个完整的 GraphQL API。您将学习如何定义模式、编写解析器、执行查询和变更。所有代码示例均可直接运行并经过实践验证。
您需要 Node.js 14 或更高版本以及 JavaScript 基础知识。如果您熟悉 Express.js,会发现 Apollo Server 非常相似——它也使用中间件并与 HTTP 配合工作。
项目安装与配置
创建一个新目录并初始化项目:
mkdir graphql-tutorialcd graphql-tutorialnpm init -y安装必要的依赖:
npm install @apollo/server graphqlnpm install nodemon --save-dev创建文件 index.js——这将是应用程序的入口点。
项目的基本结构如下:
graphql-tutorial/├── node_modules/├── index.js├── package.json└── package-lock.json创建第一个 GraphQL 服务器
我们从返回简单消息的最小服务器开始。打开 index.js 并添加以下代码:
import { ApolloServer } from '@apollo/server';import { startStandaloneServer } from '@apollo/server/standalone';
// 定义 GraphQL 模式const typeDefs = `#graphql type Query { hello: String }`;
// hello 查询的解析器const resolvers = { Query: { hello: () => '你好,世界!这是第一个 GraphQL 查询!', },};
// 创建服务器实例const server = new ApolloServer({ typeDefs, resolvers,});
// 启动服务器const { url } = await startStandaloneServer(server, { listen: { port: 4000 },});
console.log(`🚀 服务器已启动: ${url}`);使用命令 node index.js 启动服务器。打开浏览器并访问 http://localhost:4000。您将看到 Apollo Sandbox 界面,可以在其中执行查询。
在左侧面板中输入:
query { hello}然后点击 "Run" 按钮。您将收到响应:
{ "data": { "hello": "你好,世界!这是第一个 GraphQL 查询!" }}使用数据类型和复杂查询
GraphQL 允许定义自定义数据类型。让我们为 API 创建用户和图书模型。
更新文件 index.js:
import { ApolloServer } from '@apollo/server';import { startStandaloneServer } from '@apollo/server/standalone';
// 定义类型const typeDefs = `#graphql type Book { id: ID! title: String! author: String! publishedYear: Int }
type User { id: ID! name: String! email: String! books: [Book] }
type Query { books: [Book] book(id: ID!): Book users: [User] user(id: ID!): User }`;
// 测试数据const books = [ { id: '1', title: '哈利·波特', author: 'J.K. 罗琳', publishedYear: 1997 }, { id: '2', title: '指环王', author: 'J.R.R. 托尔金', publishedYear: 1954 }, { id: '3', title: '1984', author: '乔治·奥威尔', publishedYear: 1949 },];
const users = [ { id: '1', name: '伊万·伊万诺夫', email: 'ivan@example.com', bookIds: ['1', '2'] }, { id: '2', name: '安娜·彼得罗娃', email: 'anna@example.com', bookIds: ['3'] },];
// 解析器const resolvers = { Query: { books: () => books, book: (_, { id }) => books.find(book => book.id === id), users: () => users, user: (_, { i