如何使用GraphQL及GraphQL Query从REST API获取数据?
如何使用GraphQL并通过Query从REST API获取数据
一、GraphQL 基础使用步骤
1. 定义 Schema
Schema 是 GraphQL 的核心契约,用来声明可查询的数据类型、字段及查询入口。示例如下:
# 定义用户数据类型 type User { id: ID! # 感叹号表示字段非空 name: String! email: String! } # 定义查询入口 type Query { getUser(id: ID!): User # 根据ID查询单个用户 getAllUsers: [User] # 查询所有用户列表 }
2. 实现 Resolver
Resolver 是处理查询逻辑的函数,每个 Schema 字段都对应一个 Resolver,负责从数据源获取并返回对应数据。用 JavaScript 实现示例:
const resolvers = { Query: { getUser: (parent, args) => { // 此处可替换为数据库查询、文件读取等逻辑 return { id: args.id, name: "张三", email: "zhangsan@example.com" }; }, getAllUsers: () => { return [ { id: "1", name: "张三", email: "zhangsan@example.com" }, { id: "2", name: "李四", email: "lisi@example.com" } ]; } } };
3. 搭建 GraphQL 服务
以 Apollo Server 为例快速搭建服务,安装依赖后启动:
const { ApolloServer } = require('@apollo/server'); const { startStandaloneServer } = require('@apollo/server/standalone'); // 引入前文定义的Schema const typeDefs = `#graphql type User { id: ID! name: String! email: String! } type Query { getUser(id: ID!): User getAllUsers: [User] } `; // 引入前文定义的Resolver const resolvers = { /* 上述Resolver代码 */ }; async function startServer() { const server = new ApolloServer({ typeDefs, resolvers }); const { url } = await startStandaloneServer(server, { listen: { port: 4000 } }); console.log(`服务已启动:${url}`); } startServer();
4. 发送 GraphQL Query
服务启动后,访问 http://localhost:4000 打开 GraphQL Playground,即可发送查询请求:
# 查询单个用户,只返回需要的字段 query GetUser { getUser(id: "1") { id name email } } # 查询所有用户,仅获取ID和名称 query GetAllUsers { getAllUsers { id name } }
返回结果为 JSON 格式,仅包含你请求的字段,避免了 REST API 常见的过度获取问题。
二、通过 GraphQL Query 对接 REST API
GraphQL 可作为中间层,聚合多个 REST API 的数据,统一对外提供查询能力。
1. 在 Resolver 中调用 REST API
在 Resolver 里用 fetch 或 axios 调用 REST 接口,将返回数据映射到 GraphQL Schema 定义的类型。示例:
const resolvers = { Query: { getUser: async (parent, args) => { // 调用外部REST接口 const response = await fetch(`https://api.example.com/users/${args.id}`); const restUser = await response.json(); // 字段映射(若REST返回字段与GraphQL不一致,在此转换) return { id: restUser.user_id, // REST返回user_id,转为GraphQL的id name: restUser.full_name, email: restUser.email_address }; }, getAllUsers: async () => { const response = await fetch("https://api.example.com/users"); const restUsers = await response.json(); return restUsers.map(restUser => ({ id: restUser.user_id, name: restUser.full_name, email: restUser.email_address })); } } };
2. 处理嵌套数据
如果 GraphQL 类型包含嵌套字段(比如 User 关联 Posts),可在对应类型的 Resolver 中调用关联的 REST 接口:
# 更新Schema,添加Post类型及User的posts字段 type Post { id: ID! title: String! content: String! } type User { id: ID! name: String! email: String! posts: [Post]! } type Query { getUser(id: ID!): User }
对应的 Resolver 实现:
const resolvers = { Query: { getUser: async (parent, args) => { const response = await fetch(`https://api.example.com/users/${args.id}`); return await response.json(); } }, User: { // 嵌套字段的Resolver,parent参数为上层的User对象 posts: async (parent) => { const response = await fetch(`https://api.example.com/users/${parent.id}/posts`); return await response.json(); } } };
此时可一次性查询用户及关联的帖子:
query GetUserWithPosts { getUser(id: "1") { id name posts { id title } } }
3. 缓存优化
为避免重复调用相同 REST 接口,可在 Resolver 中加入缓存逻辑:
const userCache = new Map(); // 内存缓存,生产环境可替换为Redis等 const resolvers = { Query: { getUser: async (parent, args) => { if (userCache.has(args.id)) { return userCache.get(args.id); } const response = await fetch(`https://api.example.com/users/${args.id}`); const user = await response.json(); userCache.set(args.id, user); return user; } } };
内容的提问来源于stack exchange,提问作者Vijay Krishna A
相关产品推荐
相关产品推荐

