如何生成具有不同字段的相同 graphql 查询

How to generate the same graphql query with different fields

我正在使用 graphql-tag 所以我将使用该语法。

假设我有这个查询:

const query = gql`
 query user(id: String) {
  user(id: $id) {
   id
  }
 }
`

如果在不同的调用中重用同一个查询文档节点的最佳模式是什么我想要字段 usernameemail 除了 id 而不必重写整个再次查询:

const query = gql`
 query user(id: String) {
  user(id: $id) {
   id
   username
   email
  }
 }
`

我在前端使用 react-apollo 如果这让事情变得更有趣的话。

编辑:

只是为了澄清......像这样

const userIdFrag = gql`
  fragment UserId on User {
    id
  }
`

const fullUserFrag = gql`
  fragment FullUser on User {
    id
    username
    email
  }
`

const generateQuery = (documentNode) => {
  return gql`
   query user(id: String) {
      user(id: $id) {
       ...documentNode
      }
     }
     ${documentNode}
  `
}

const idQuery = generateQuery(userIdFrag);
const fullUserQuery = generateQuery(fullUserFrag);

(以上确实有效,但在控制台中给我来自 graphql 的错误,这让我相信这不是我应该做的事情)

我不是这个话题的专家,但这是我能够找到的。 (如果您发现我的假设有任何错误,请告诉我)。

我发现 this article 对动态生成 gql queries/mutations 有一些好处。静态方法似乎给您带来了一些不错的好处,尽管它需要输入更多内容。

但是,如果您确实需要动态字段,我还没有发现使用 GraphQL 提供的 @skip 指令有什么不好。 Here the docs ref.

以在react-apollo they also have it in their docs.

中使用的情况为例

因此,您的代码最终可能看起来像这样:

const query = gql`
 query user($id: String, $skipUserMeta: Boolean!) {
  user(id: $id) {
   id
   username @skip(if: $skipUserMeta)
   email @skip(if: $skipUserMeta)
  }
 }
`

您只需将 skipUserMeta 作为变量与 id 字段一起传递。

注意:我实际上找到了一个视频,其中讨论了 the exact same approach here

根据您的评论,以下应该有效:


const generateQuery = (documentNode, fragment) => {
  return gql`
   query user(id: String) {
      user(id: $id) {
       ...${fragment}
      }
     }
     ${documentNode}
  `
}

const idQuery = generateQuery(userIdFrag, 'UserId');
const fullUserQuery = generateQuery(fullUserFrag, 'FullUser');

基本上使用的片段名称是实际需要展开的片段名称,而整个 documentNode 对象放在末尾,在查询的结束括号之后