如何使用不同的字段生成相同的 graphql 查询
Posted
技术标签:
【中文标题】如何使用不同的字段生成相同的 graphql 查询【英文标题】:How to generate the same graphql query with different fields 【发布时间】:2019-07-05 06:57:39 【问题描述】:我正在使用graphql-tag
,所以我将使用该语法。
假设我有这个查询:
const query = gql`
query user(id: String)
user(id: $id)
id
`
如果在不同的调用中,除了id
之外,我还想要字段username
和email
,而无需再次重写整个查询,那么重用同一个查询文档节点的最佳模式是什么:
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 出现错误,这让我相信这不是我应该做的事情)
【问题讨论】:
您可以查看片段 - apollographql.com/docs/react/advanced/fragments.html,尽管您仍然需要定义查询 2 次span> 是的,我知道片段,我想知道是否有更好的方法可以避免每次都写查询签名 您遇到的错误是什么? @ric0 错误基本上说“在 graphql 查询中未使用 documentNode”,即使 $documentNode 片段正在添加到其中 【参考方案1】:根据您的评论,以下应该有效:
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 对象放在最后,在查询的右括号之后
【讨论】:
这很有效,现在我看到它写出来了,这更有意义。我可能会做出的一项更改是,您实际上可以从位于...的 documentNode 获取片段的名称。node.definitions[0].name.value
是的,当然。我没想到,你的方式更有效。【参考方案2】:
我不是该主题的专家,但这是我能够找到的。 (如果您发现我的假设有任何错误,请告诉我)。
我发现this article 对动态生成gql
查询/突变有一些好处。使用静态方法似乎可以获得一些不错的好处,尽管它需要更多的输入。
但是,如果您确实需要动态字段,我找不到任何关于使用 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的视频
【讨论】:
以上是关于如何使用不同的字段生成相同的 graphql 查询的主要内容,如果未能解决你的问题,请参考以下文章
如何在两个字段 prisma-graphql 中使用相同的生成 ID