如何以优雅哈希风格将对象作为键实现GraphQL配置复用
解决方案
针对你需要复用GraphQL字段与权限配置的需求,这里有几个比WeakMap更简洁直观的实现方式:
方案一:用数组存储映射关系,动态生成所需结构
把每个字段对应的权限规则用数组存起来,再通过reduce分别生成Schema需要的fields对象和Shield需要的权限配置,既避免重复代码,又保持可读性:
const { query1 } = require('query1') const { query2 } = require('query2') const { query3 } = require('query3') // 统一声明字段与权限的映射 const fieldPermissions = [ { field: query1, rule: user }, { field: query2, rule: user }, { field: query3, rule: admin }, ] // 生成Schema的fields对象(假设query对象有name属性对应GraphQL字段名) const queryFields = fieldPermissions.reduce((acc, { field }) => { acc[field.name] = field return acc }, {}) // 生成Shield的权限配置 const permissions = shield({ Query: fieldPermissions.reduce((acc, { field, rule }) => { acc[field.name] = rule return acc }, {}) }) // 构建Schema const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: "Query", fields: queryFields }) })
如果你的query变量名就是GraphQL字段名(比如query1对应字段名"query1"),可以简化字段名的获取逻辑:
const queryFields = fieldPermissions.reduce((acc, { field }) => { const fieldName = Object.keys({ field })[0] // 自动取变量名作为字段名 acc[fieldName] = field return acc }, {})
方案二:封装辅助函数统一处理
如果需要多次复用这类逻辑,可以封装工具函数,输入映射数组直接返回fields和权限配置结构:
function buildQueryConfig(fieldPermissions) { const fields = {} const queryPermissions = {} for (const { field, rule } of fieldPermissions) { const fieldName = field.name || Object.keys({ field })[0] fields[fieldName] = field queryPermissions[fieldName] = rule } return { fields, queryPermissions } } // 使用示例 const { fields: queryFields, queryPermissions } = buildQueryConfig([ { field: query1, rule: user }, { field: query2, rule: user }, { field: query3, rule: admin }, ]) const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: "Query", fields: queryFields }) }) const permissions = shield({ Query: queryPermissions })
方案三:利用对象解构与动态键名
如果字段变量名和GraphQL字段名完全一致,这是最简洁的方案:
const { query1 } = require('query1') const { query2 } = require('query2') const { query3 } = require('query3') // 定义所有Query字段 const queryFields = { query1, query2, query3 } // 定义权限规则,直接复用字段变量名作为键 const queryPermissions = { query1: user, query2: user, query3: admin } // 构建Schema和权限 const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: "Query", fields: queryFields }) }) const permissions = shield({ Query: queryPermissions })
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

