You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何以优雅哈希风格将对象作为键实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 08:15:43