【问题标题】:Use GraphQL to retrieve an object that contains an array of objects with different schemas使用 GraphQL 检索包含具有不同模式的对象数组的对象
【发布时间】:2019-09-05 22:59:06
【问题描述】:

我正在尝试编写一个查询来检索具有属性linkedCards 的对象,其中包含具有不同架构的对象数组。

我有 3 种不同的架构(内置于 Contentful):

CardA 示例:

{
    id: 42,
    productName: 'Laptop',
    price: 999
}

卡片示例:

{
    id: 999,
    title: 'Buy our refurbished Laptops today!'
}

CardC 示例:

{
    id: 100,
    linkedCards: [
        {
            id: 42,
            productName: 'Laptop',
            price: 999
        },
        {
            id: 999,
            title: 'Buy our refurbished Laptops today!'
        }
    ]
}

查询:

allCardC() {
    nodes {
        linkedCards {
            id
            title
        }
    }
}

当我尝试运行以下 GraphQL 查询时,我得到 "Cannot query field "title" on type "CardACardBUnion". Did you mean to use an inline fragment on "CardA" or "CardB"?"

有没有内置的方法可以做到这一点,或者我可以以某种方式使用CardACardB 的ID?也许有一个查询来获取linkedCards 中卡片的 ID,而另一个查询来获取所述卡片?

【问题讨论】:

    标签: graphql gatsby graphql-js contentful


    【解决方案1】:

    如错误所示,在查询解析为联合的字段时,您需要使用inline fragment

    allCardC {
        nodes {
            linkedCards {
                ... on CardA {
                  id
                  productName
                  price
                }
                ... on CardB {
                  id
                  title
                }
            }
        }
    }
    

    片段可以在选择集中内联定义。这样做是为了根据运行时类型有条件地包含字段。

    与接口或常规对象类型不同,联合不指定任何特定字段,仅指定构成联合的类型。这意味着返回联合的字段的选择集必须始终使用片段根据字段解析为的实际类型有条件地指定字段。

    这就像说,“如果这是返回对象的实际类型,请请求这些字段”。

    【讨论】:

    • 这正是我想要的!谢谢丹尼尔! ?
    • 太棒了,在类似的问题上停留了几个小时。 @ChristophAnderson 应该接受这个答案。
    【解决方案2】:

    您可能会发现使用 GraphQL interface 指定每种卡片类型共有的字段很有用。

    interface Card {
      id: ID!
    }
    # type CardA implements Card { ... }
    type CardB implements Card {
      id: ID!
      title: String!
    }
    type CardC implements Card {
      id: ID!
      linkedCards: [Card!]!
    }
    

    正如@DanielRearden 的回答所暗示的,您仍然需要使用(内联)片段来选择特定于一种卡片类型的字段,但现在您知道每张卡片都有一个id 字段,您可以直接选择它。

    allCardC {
        nodes {
            linkedCards {
                id
                ... on CardB { title }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-26
      • 1970-01-01
      • 2020-01-12
      • 2021-09-07
      • 1970-01-01
      • 2022-11-11
      • 2016-01-30
      • 1970-01-01
      • 2018-04-15
      相关资源
      最近更新 更多