如何从数组动态构建GraphQL片段并生成查询?
动态构建GraphQL查询(基于片段数组)
我了解到构建动态GraphQL查询的推荐方式是使用片段,静态场景下的示例如下:
const series1Q = gql` fragment series1 on timeseriesDataQuery { series1: timeseriesData(sourceId: "source1") { data { time value } } } ` const series2Q = gql` fragment series2 on timeseriesDataQuery { series2: timeseriesData(sourceId: "source2") { data { time value } } } `
随后将这些片段拼入主查询:
export const mainQuery = gql` query fetchData { ...series1 ...series2 } ${series1Q} ${series2Q} `
但我的场景中用户可添加任意数量的项,最终会得到一个片段数组:
const series = [ gql` fragment series1 on timeseriesDataQuery { series1: timeseriesData(sourceId: "source1") { data { time value } } } `, gql` fragment series2 on timeseriesDataQuery { series2: timeseriesData(sourceId: "source2") { data { time value } } } ` ]
我尝试过多种拼接方式均出现格式错误,例如:
export const mainQuery = gql` ${...series} query fetchData { ...series1 ...series2 } `
或者:
export const mainQuery = gql` {...series} query fetchData { ...series1 ...series2 } `
请问有没有人实现过从数组创建动态GraphQL查询?
解决方案
要处理动态片段数组,需分两步完成:生成查询内的片段引用列表,以及拼接所有片段定义。
步骤1:生成动态片段引用
从片段数组中提取每个片段的名称,生成对应的...片段名语句并拼接成字符串,插入到查询的字段位置。
步骤2:拼接片段定义
将数组中的所有片段用join('')拼接后,插入到主查询的末尾。
代码示例(片段名称按顺序生成)
// 从片段数组提取名称,假设名称是series1、series2格式 const fragmentNames = series.map((_, index) => `series${index + 1}`); // 生成片段引用字符串 const fragmentRefs = fragmentNames.map(name => `...${name}`).join('\n '); export const mainQuery = gql` query fetchData { ${fragmentRefs} } ${series.join('')} `
代码示例(片段名称不固定时)
如果片段名称不是按顺序生成的,可以通过正则从片段内容中提取名称:
// 从片段字符串中提取名称的工具函数 const getFragmentName = (fragment) => { const match = fragment.loc.source.body.match(/fragment (\w+) on/); return match ? match[1] : ''; }; const fragmentNames = series.map(getFragmentName).filter(Boolean); const fragmentRefs = fragmentNames.map(name => `...${name}`).join('\n '); export const mainQuery = gql` query fetchData { ${fragmentRefs} } ${series.join('')} `
核心逻辑是利用模板字符串结合数组join方法,完成动态片段引用和定义的拼接,避免语法错误。
内容的提问来源于stack exchange,提问作者LuxuryWaffles
相关产品推荐
相关产品推荐

