Graphql将多个查询合并(合并)为一个?

时间:2019-02-18 09:28:56

标签: javascript graphql

我正在尝试使用JavaScript将多个Graphql查询合并为一个查询。
我正在寻找这样的东西:

let query3 = mergeQueries(query1, query2);

我们不会事先知道将合并哪些查询。

假设我有这样的查询:

输入查询1:

{
  post(id: 1234) {
    title
    description
  }
}

输入查询2:

{
  post(id: 1234) {
    tags
    author {
      name
    }
  }
}

然后我希望结果query3为:
结果查询3:

{
  post(id: 1234) {
    title
    tags
    description
    author {
      name
    }
  }
}

这与lodash _.merge()对于JSON对象具有相同的功能,但随后是Graphql查询而不是JSON对象。

3 个答案:

答案 0 :(得分:3)

我的回答有点冗长,无法发表评论,所以我决定在此处写一个直接答案。首先,我认为这两个评论确实有帮助。有一种解决方案,让两个查询共享一个HTTP请求,这可能已经是您要寻找的优化。此外,合并查询并非无关紧要。要做到这一点,需要付出很多努力。不仅片段会增加难度,而且还必须考虑变量。据我所知,没有公开的解决方案可以做到这一点,所以您必须自己做。我也没有听说过这样做的公司。我认为没有解决方案的事实表明这样做可能不值得。

我只能猜测您的问题,但是减少前端应用程序发送的查询数量的另一种方法是利用片段。尽管您的片段不能包含变量,但是健康的组件结构仍然非常适合片段:

fragment PostHeader on Post {
  title
  description
}

fragment PostMeta on Post {
  tags
  author {
    name
  }
}

query {
  post(id: 1234) {
    ...PostHeader
    ...PostMeta
  }
}

答案 1 :(得分:1)

由于参数化的片段,您可以考虑变量!假设fragment PostHeader on RootQueryType { post(id: $id) { tags author { name } } } fragment PostMeta on RootQueryType { post(id: $id) { tags author { name } } } # ID being the id type query(id: ID! = 1234) { ...PostHeader ...PostMeta } 是根查询类型的字段,则参考上述示例的组合查询将是:

{"Name":"one","age":"22"}

或者在现实情况下,您将动态传递ID(例如,在您的帖子请求中),请参见:https://graphql.org/learn/queries/#variables

答案 2 :(得分:-1)

我为此写了一个库:https://github.com/domasx2/graphql-combine-query

import comineQuery from 'graphql-combine-query'

import gql from 'graphql-tag'

const fooQuery = gql`
  query FooQuery($foo: String!) {
    getFoo(foo: $foo)
  }
`

const barQuery = gql`
  query BarQuery($bar: String!) {
    getBar(bar: $bar)
  }
`

const { document, variables } = combineQuery('FooBarQuery')
  .add(fooQuery, { foo: 'some value' })
  .add(barQuery, { bar: 'another value' })

console.log(variables)
// { foo: 'some value', bar: 'another value' }

print(document)
/*
query FooBarQuery($foo: String!, $bar: String!) {
   getFoo(foo: $foo)
   getBar(bar: $bar)
}
*/

相关问题