连接,边,节点:如何使用节点的子类型

时间:2019-03-06 19:13:08

标签: graphql

我遵循阿波罗中的连接,边缘,节点,中继的概念。 我使用Node { id: ID! }界面。我有一组都是“组”的实体,差异很小。我想将这些模型建模为单个Connection,但不确定如何做到:

     # simplified for example
    interface Group {
        id: ID!
        type: String!
    }
    type WallGroup implements Node & Group {
        id: ID!
        type: String!
    }
    type Event implements Node & Group {
        id: ID!
        type: String!
        dteStart: DateTime!
        dteEnd: DateTime!
    }
    type GroupEdge implements Edge {
        cursor: String!
        node: Group!
    }
    type GroupConnection implements Connection {
        edges: [GroupEdge!]!
        pageInfo: PageInfo!
        totalCount: Int!
    }

这将产生错误,因为GroupEdge期望节点到Node。是的,但是Group接口不是,因此失败。

我尝试的另一件事是

    union AllGroup = WallGroup | Event
    type GroupEdge implements Edge {
        cursor: String!
        node: AllGroup!
    }

但这会导致相同的问题。显然,并集失去了在WallGroupEvent上实现的Node接口的概念。

关于如何对此建模的任何想法,还是我应该复制所有内容?

1 个答案:

答案 0 :(得分:0)

Relay specification仅要求您的架构包括一个Node接口-创建兼容中继的接口时,通常不会为Connection和Edge创建接口。

Relay需要一个Node接口的原因是允许我们通过id查询任何Node。但是,通常不需要返回多个边之一或多个连接之一的字段。因此,通常不需要为边缘或连接创建接口。这是您通常要做的:

interface Node {
  id: ID!
}

interface Group {
    id: ID!
    type: String!
}

type GroupA implements Node & Group {
    id: ID!
    type: String!
    # other fields
}

type GroupA implements Node & Group {
    id: ID!
    type: String!
    # other fields
}

type GroupEdge {
    cursor: String!
    node: Group!
}

type GroupConnection {
    edges: [GroupEdge!]!
    pageInfo: PageInfo!
    totalCount: Int!
}

根据spec,“ [实现]对象类型必须为接口中定义的每个字段都包含一个具有相同名称的字段。因此,如果接口指定字段为Foo类型,则即使FooBar是接口且Foo,实现类型也不能使字段类型为FooBar实现它。不幸的是,这意味着实际上不可能像您尝试的那样使用接口。

如果您想利用接口来提供各种安全网络并确保实现类型是一致的,则 可以 可以执行以下操作:

interface Connection {
  pageInfo: PageInfo!
  # don't specify edges
}

interface Edge {
  cursor: String!
  # don't specify node
}

这样,您可以确保实现类型中存在诸如pageInfocursor之类的字段,具有正确的类型并且不为空。但是,这种架构级别的验证确实是您添加和实现这两个接口的唯一好处。