GraphQLInterfaceType中的接口是什么?

时间:2018-03-15 20:35:13

标签: javascript graphql graphql-js

我有以下代码段:

export const NodeInterface = new GraphQLInterfaceType({
  name: 'Node',
  fields: {
    id: {
      type: new GraphQLNonNull(GraphQLID)
    }
  },
  resolveType: (source) => {
    if (source.__tableName === tables.users.getName()) {
      return UserType;
    }
    return PostType;
  }
});

和使用该界面的GraphQLObjectType

export const PostType = new GraphQLObjectType({
  name: 'Post',
  interfaces: [ NodeInterface ],
  fields: {
    id: {
      type: new GraphQLNonNull(GraphQLID),
      resolve: resolveId
    },
    createdAt: {
      type: new GraphQLNonNull(GraphQLString),
    },
    body: {
      type: new GraphQLNonNull(GraphQLString)
    }
  }
});

我有什么定义界面的?

1 个答案:

答案 0 :(得分:1)

在GraphQL中,接口有两个目的:

  1. 他们确保实现它们的类型也实现特定字段。例如,此处的Node接口具有id字段 - 这意味着实现Node接口的任何类型都需要具有id字段(并且{ {1}}需要是接口中的ID标量)对于那些参数也是如此 - 接口中字段的任何参数也必须存在于实现类型的匹配字段中。

  2. 当字段需要两种或更多种类型时,可以使用它们。一个字段将始终解析为一个类型或标量,但是,通过使用我们在架构中指示字段可以解析为一个集合的接口(或联合)类型。

  3. 因此,假设我们在您的代码段中有id类似,有些类型实现了它,以及返回节点的查询:

    Node

    在我们的示例中,interface Node { id: ID! } type Foo implements Node { id: ID! someFooField: String! someOtherFooField: Int! } type Bar implements Node { id: ID! someBarField: String! someOtherFooField: Int! } type Query { getNode(id: ID!): Node! } 可以解析为getNodeFoo。当我们编写查询时,我们不知道哪一个将被解析。但是因为我们知道接口需要Bar字段,所以我们可以编写如下的查询:

    id

    如果我们还需要查询query OperationName { getNode(id: "SOME_ID"){ id } } ,我们也不能这样做:

    someBarField

    因为query OperationName { getNode(id: "SOME_ID"){ id someBarField } } 没有该字段。相反,我们必须使用一个片段,如下所示:

    Foo

    然后会返回query OperationName { getNode(id: "SOME_ID"){ id ... on Bar { someBarField } } } ,但前提是该字段解析为someBarField类型。如果是Bar,则只返回ID。同样,您可以从实现相同接口的任何类型请求非共享字段:

    Foo

    最后但同样重要的是,应该提到的是,工会的工作方式非常相似。但是,与接口不同,没有为联盟定义的共享字段,因此类型不会“实现”联合,它只是一个联盟的一部分。这意味着在请求返回union的字段时,您将始终必须使用片段,因为没有要请求的共享字段。