使用GraphQL检索对象,该对象包含具有不同架构的对象数组

时间:2019-04-15 22:25:41

标签: graphql gatsby graphql-js contentful

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

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

CardA示例:

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

CardB示例:

{
    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,而有另一个查询要获取所说的卡?

2 个答案:

答案 0 :(得分:2)

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

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

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

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

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

答案 1 :(得分:2)

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

Glide.with(***activity_main***)

@DanielRearden的答案表明您仍然需要使用(内联)片段来选择特定于其中一种卡类型的字段,但是现在您知道每个卡都有一个interface Card { id: ID! } # type CardA implements Card { ... } type CardB implements Card { id: ID! title: String! } type CardC implements Card { id: ID! linkedCards: [Card!]! } 字段,您可以选择直接。

id