GraphQL是一种用于API的查询语言,由Facebook开发并开源,它允许客户端精确指定需要获取的数据,避免了传统REST API中数据冗余或不足的问题,在JavaScript生态中有着丰富的工具支持,非常适合现代API开发场景。

GraphQL核心概念
在开发之前需要先了解GraphQL的几个核心概念,这些是后续开发的基础。
- Schema:定义API的所有可用数据类型和查询结构的蓝图,是GraphQL服务的核心。
- 类型系统:GraphQL有自带的类型系统,支持标量类型(String、Int、Boolean等)和自定义对象类型。
- 解析器:负责处理每个查询字段的逻辑,从数据源获取数据并返回给客户端。
- 查询和变更:查询用于获取数据,变更用于修改数据,对应REST API中的GET和POST/PUT/DELETE操作。
环境准备与依赖安装
我们使用Node.js环境,配合Apollo Server框架来搭建GraphQL服务,Apollo Server是JavaScript生态中最流行的GraphQL服务端框架,使用简单且功能完善。首先初始化项目并安装依赖:
# 初始化Node.js项目 npm init -y # 安装Apollo Server和GraphQL核心依赖 npm install @apollo/server graphql
搭建基础GraphQL服务
定义Schema和解析器
首先定义最简单的Schema,包含一个查询字段获取问候语,对应的解析器返回固定字符串:
const { ApolloServer } = require('@apollo/server');
const { startStandaloneServer } = require('@apollo/server/standalone');
// 定义GraphQL Schema
const typeDefs = `
type Query {
# 获取问候语的查询字段
hello: String
}
`;
// 定义解析器,对应Schema中的每个字段
const resolvers = {
Query: {
hello: () => 'Hello GraphQL',
},
};
// 创建Apollo Server实例
const server = new ApolloServer({
typeDefs,
resolvers,
});
// 启动服务
async function startServer() {
const { url } = await startStandaloneServer(server, {
listen: { port: 4000 },
});
console.log(`GraphQL服务运行在 ${url}`);
}
startServer();
运行上述代码后,访问http://localhost:4000就可以打开Apollo Sandbox,这是内置的GraphQL查询测试工具,在左侧输入查询语句即可测试接口。
测试查询
在Apollo Sandbox的查询编辑区输入以下查询语句,点击执行按钮就能看到返回结果:
query {
hello
}
返回结果会是{ "data": { "hello": "Hello GraphQL" } },说明基础服务已经正常工作。
实现带参数的查询
实际开发中查询通常需要接收参数,比如根据ID获取用户信息,下面演示如何实现带参数的查询:
// 模拟用户数据
const users = [
{ id: '1', name: '张三', age: 25 },
{ id: '2', name: '李四', age: 30 },
];
// 更新Schema,添加用户类型和带参数的查询
const typeDefs = `
type User {
id: ID
name: String
age: Int
}
type Query {
hello: String
# 根据ID查询用户,参数id为必填的ID类型
getUserById(id: ID!): User
}
`;
// 更新解析器,实现getUserById的逻辑
const resolvers = {
Query: {
hello: () => 'Hello GraphQL',
getUserById: (parent, args) => {
// args是查询传递的参数对象,这里查找id匹配的用户
return users.find(user => user.id === args.id);
},
},
};
对应的查询语句可以这样写,查询ID为1的用户的姓名和年龄:
query {
getUserById(id: "1") {
name
age
}
}
返回结果会只包含请求的两个字段:{ "data": { "getUserById": { "name": "张三", "age": 25 } } },体现了GraphQL按需获取数据的特性。
实现数据变更操作
除了查询,GraphQL也支持数据变更,对应数据的增删改操作,下面添加一个新增用户的变更:
// 更新Schema,添加变更类型
const typeDefs = `
type User {
id: ID
name: String
age: Int
}
type Query {
hello: String
getUserById(id: ID!): User
}
type Mutation {
# 新增用户的变更,接收name和age参数,返回新增的用户
addUser(name: String!, age: Int!): User
}
`;
// 更新解析器,添加Mutation对应的逻辑
const resolvers = {
Query: {
hello: () => 'Hello GraphQL',
getUserById: (parent, args) => {
return users.find(user => user.id === args.id);
},
},
Mutation: {
addUser: (parent, args) => {
// 生成新的用户ID,这里简单用数组长度加1的方式
const newUser = {
id: String(users.length + 1),
name: args.name,
age: args.age,
};
users.push(newUser);
return newUser;
},
},
};
调用变更的查询语句如下,新增一个名为王五、年龄28的用户:
mutation {
addUser(name: "王五", age: 28) {
id
name
age
}
}
执行后就能看到新增用户的信息被返回,再次查询用户列表也能看到新用户已经存在。
常见问题与注意事项
- Schema定义时要注意字段的类型是否匹配,必填字段需要添加感叹号标记。
- 解析器的参数顺序固定,第一个是父对象,第二个是参数,第三个是上下文,第四个是查询信息,通常只需要使用前两个。
- 实际项目中解析器通常会连接数据库获取数据,而不是直接使用内存中的模拟数据。
- 需要处理查询和变更中的错误,比如参数不合法、数据不存在等情况,返回合适的错误信息。
GraphQL并不是要完全替代REST API,而是提供了更灵活的数据获取方式,开发者可以根据项目需求选择合适的方案,或者两者结合使用。
JavaScriptGraphQLAPI开发Apollo_Server修改时间:2026-06-26 21:42:39