Apollo Server优化:仅查询编码时跳过解析器
在Apollo Server中避免不必要数据库查询的优雅实现
你可以通过解析GraphQL的info参数判断客户端实际请求的字段,仅当需要查询Country的name字段时才去访问nationality表,否则直接利用User对象已有的nationalityIsoCode返回结果,具体实现如下:
方法一:手动解析info参数提取请求字段
无需额外依赖,直接解析info对象中的选择集:
const resolvers = { User: { nationality: async (parent, _, context, info) => { // 提取客户端请求的Country字段列表 const requestedCountryFields = info.fieldNodes[0].selectionSet.selections .map(selection => selection.name.value); // 仅请求isoCode时,直接返回包含编码的对象,无需查询数据库 if (requestedCountryFields.length === 1 && requestedCountryFields.includes('isoCode')) { return { isoCode: parent.nationalityIsoCode }; } // 存在其他字段时,查询nationality表获取完整数据 return context.db.nationality.findOne({ where: { isoCode: parent.nationalityIsoCode } }); } } };
方法二:使用graphql-fields简化字段提取
如果觉得手动解析info繁琐,可以用graphql-fields工具包快速获取请求字段集合:
const graphqlFields = require('graphql-fields'); const resolvers = { User: { nationality: async (parent, _, context, info) => { const requestedFields = graphqlFields(info); // 若未请求name字段,直接返回isoCode if (!requestedFields.name) { return { isoCode: parent.nationalityIsoCode }; } // 否则查询数据库 return context.db.nationality.findOne({ where: { isoCode: parent.nationalityIsoCode } }); } } };
注意事项
- 确保返回对象符合
Country类型定义:即使只返回isoCode,也要保证结构匹配类型要求,避免客户端解析报错。 - 若后续
Country类型新增字段,需同步更新判断逻辑,避免遗漏必要的数据库查询。
内容的提问来源于stack exchange,提问作者Tamlyn
相关产品推荐
相关产品推荐

