如何在GraphQL中展平对象?

时间:2017-01-16 02:00:25

标签: graphql

我有一个通过我的GraphQL服务器公开的嵌套javascript类(见下文)。我可以编写一个将这个复杂结构公开为单个对象的GQL模式吗? (又称扁平)。

嵌套对象

interface Promotion {
    id
    type 
    data: PromotionType1 | PromotionType2 
}

interface PromotionType1 {
    a
    b 
}

interface PromotionType2 {
    c
    d
}

访问对象所需的GQL查询

我想编写一个GQL架构,以便我可以按如下方式查询此对象:

promotion(id: "123") {
    id
    type
    ... on PromotionType1 {
        a
        b
    }
    ... on PromotionType2 {
        c
        d
    }
}

GQL可以实现吗?

2 个答案:

答案 0 :(得分:1)

如果重构嵌套对象,可以使用GraphQLUnitType and GraphQLInterfaceType使GraphQL查询能够访问该对象。您似乎打算在设计促销类型时使用继承,并最终将子类型作为父类型中的字段。相反,结构应该是:

interface Promotion {
    id
    type 
}

interface PromotionType1 extends Promotion {
    a
    b 
}

interface PromotionType2 extends Promotion {
    c
    d
}

促销是基本类型。我们可以将它作为GraphQLInterfaceType:

const PromotionType = new GraphQLInterfaceType({
  name: 'PromotionInterface',
  fields: {
    id: { type: GraphQLID },
    type: { type: GraphQLString }
  }
});

您需要PromotionType1PromotionType2的实例。因此,这些可以是GraphQLObjectType

const PromotionType1 = new GraphQLObjectType({
  name: 'PromotionType1',
  interfaces: [ PromotionType ],
  fields: {
    id: { type: GraphQLID },
    type: { type: GraphQLString },
    a: { type: GraphQLString },
    b: { type: GraphQLString },
  },
  isTypeOf: value => value instanceof PromotionType1
});

const PromotionType2 = new GraphQLObjectType({
  name: 'PromotionType2',
  interfaces: [ PromotionType ],
  fields: {
    id: { type: GraphQLID },
    type: { type: GraphQLString },
    c: { type: GraphQLString },
    d: { type: GraphQLString },
  },
  isTypeOf: value => value instanceof PromotionType2
});

如果你有针对GraphQL的JS类Promotion1类型PromotionType1Promotion2 PromotionType2,那么用于公开促销数据的GraphQLObjectType将是:

var Promotion = new GraphQLUnionType({
  name: 'Promotion',
  types: [ PromotionType1, PromotionType2 ],
  resolveType(value) {
    if (value instanceof Promotion1) {
      return PromotionType1;
    }
    if (value instanceof Promotion2) {
      return PromotionType2;
    }
  }
});

然后,您可以使用以下方式查询促销数据:

promotion(id: "123") {
    id,
    type,
    ... on PromotionType1 {
        a,
        b,
    }
    ... on PromotionType2 {
        c,
        d,
    }
}

您可以查看this example

答案 1 :(得分:0)

一种可能的解决方案是在解析器中展平对象结构。这样可以避免在GQL模式中执行任何复杂操作。