如何在graphql-js中定义对象类型解析器及处理嵌套字段解析
刚好我之前也遇到过类似的场景,在graphql-js里处理返回类实例、数据嵌套在info属性的情况,有几个实用的方案可以解决你的问题:
方案1:给单个字段添加resolve函数
这是最直接的方式,在定义GraphQLObjectType的字段时,明确指定resolve函数,从返回的类实例的info属性中提取对应字段值:
const TruckDriver: GraphQLObjectType = new GraphQLObjectType({ name: 'TruckDriver', fields: () => ({ id: { type: GraphQLString, // 从类实例的info属性里读取id字段 resolve: (source) => source.info.id }, // 其他字段可以依葫芦画瓢,比如添加name字段 name: { type: GraphQLString, resolve: (source) => source.info.name } }), })
方案2:用工具函数批量生成字段配置
如果你的对象类型有很多字段,重复写resolve会非常繁琐。可以封装一个通用工具函数,自动生成指向source.info的字段配置,减少重复代码:
// 通用工具函数:自动生成从source.info取值的字段配置 const infoField = (type: GraphQLType) => ({ type, resolve: (source, _, __, { fieldName }) => { // 通过fieldName动态匹配info里的对应字段 return source.info[fieldName] } }) // 使用工具函数定义TruckDriver类型的字段 const TruckDriver: GraphQLObjectType = new GraphQLObjectType({ name: 'TruckDriver', fields: () => ({ id: infoField(GraphQLString), name: infoField(GraphQLString), licenseNumber: infoField(GraphQLString) }), })
方案3:全局设置默认字段解析器
如果你的应用里有很多类似的类型(返回的实例都把数据存在info属性中),可以在构建GraphQLSchema时设置全局的defaultFieldResolver,一次性处理所有这类字段的解析逻辑,效率最高:
const schema = new GraphQLSchema({ query: YourQueryType, // 替换成你的查询类型 mutation: YourMutationType, // 替换成你的变更类型 defaultFieldResolver: (source, args, context, info) => { // 可以指定需要特殊处理的类型列表,避免影响其他类型的解析 const infoBasedTypes = ['TruckDriver', 'Cargo', 'Delivery']; if (infoBasedTypes.includes(info.parentType.name) && source.info) { // 从info属性中读取当前字段的值 return source.info[info.fieldName]; } // 其他类型沿用graphql-js的默认解析逻辑(直接取source[fieldName]) return source[info.fieldName]; } })
补充说明一下:你之前觉得对象类型本身不支持解析器配置是对的——graphql-js的GraphQLObjectType确实没有顶层的resolve配置,字段级的resolve函数或全局默认解析器是官方推荐的处理字段数据映射的方式。
内容的提问来源于stack exchange,提问作者Alexander Knyazev
相关产品推荐
相关产品推荐

