如何使用Apollo GraphQL查询参数序列化响应以满足缓存需求
Apollo GraphQL 动态响应结构实现方案
以下两种实现分别对应你需要的两种返回结构:
实现第二种结构(嵌套holidays字段,符合GraphQL规范,更推荐)
GraphQL 原生不支持动态字段名的Object类型,所以需要引入自定义JSON标量处理:
- 安装
graphql-scalars依赖,在Schema中声明JSON标量:
scalar JSON type Query { holidays(startDate: String!, endDate: String!, newDate: String!): JSON! }
- 在字段解析器中直接构造目标结构:
// 从graphql-scalars导入JSON标量实现 const { GraphQLJSON } = require('graphql-scalars'); const resolvers = { JSON: GraphQLJSON, Query: { holidays: async (_, { startDate, endDate, newDate }) => { // 原有业务逻辑,查询得到假期的price和food数据 const originData = await getHolidayRawData(startDate, endDate); // 按要求构造返回结构 return { [newDate]: originData } } } }
调用后即可得到你需要的第二种响应结构:
{ "data": { "holidays": { "2024-10-01": { "price": 23, "food": ["bananas"] } } } }
实现第一种结构(根级别动态key)
如果需要将动态key放在data根节点,需要使用Apollo Server的formatResponse全局钩子修改响应格式:
- 先定义常规Schema和解析器:
type HolidayInfo { price: Float food: [String] } type Query { holidays(startDate: String!, endDate: String!, newDate: String!): HolidayInfo! }
- 解析器返回业务数据的同时附带newDate参数:
const resolvers = { Query: { holidays: async (_, { startDate, endDate, newDate }) => { const originData = await getHolidayRawData(startDate, endDate); // 附加newDate参数,后续钩子处理时用 return { ...originData, _dynamicKey: newDate } } } }
- 初始化Apollo Server时配置响应转换钩子:
const server = new ApolloServer({ typeDefs, resolvers, formatResponse: (res) => { if (res.data?.holidays) { const { _dynamicKey, ...holidayData } = res.data.holidays; // 替换根data结构 res.data = { [_dynamicKey]: holidayData } } return res; } })
调用后即可得到根级别带动态key的第一种响应结构。
缓存适配提示
如果是为了适配Apollo Client缓存,更推荐使用第二种结构,配合Apollo Client的typePolicies配置自定义缓存key即可实现按newDate参数缓存,无需修改根响应结构。
内容的提问来源于stack exchange,提问作者tachko
相关产品推荐
相关产品推荐

