联合类型
|
这是 GraphQL Library 7 版本的文档。对于长期支持 (LTS) 版本 5,请参考 GraphQL Library 5 LTS 版本。 |
本页介绍了如何在关系上下文中使用联合类型,并举例说明了如何在查询和变更(Mutation)中使用它们。
数据模型
以如下图形为例,其中 User 类型通过 HAS_CONTENT 关系连接到 Content 类型,而 Content 是 Blog 和 Post 两个节点类型的联合。
示例数据库数据
考虑一个由以下示例数据组成的数据库,它遵循上述数据模型。
编写类型定义
从概念上讲,Blog 和 Post 都是归属于 User 的“内容”类型。然而,它们是根本不同的内容类型,具有不同的字段,因此可以通过联合类型将它们组合在一起。
union Content = Blog | Post
type Blog @node {
title: String
posts: [Post!]! @relationship(type: "HAS_POST", direction: OUT)
}
type Post @node {
content: String
}
type User @node {
name: String
content: [Content!]! @relationship(type: "HAS_CONTENT", direction: OUT)
}
查询联合类型
联合类型对于建模那些指向多个不共享公共字段的不同节点类型的关系非常有用。
查询联合类型的关系字段时,必须使用内联片段(inline fragments)来指定联合中每种类型要返回的字段。
注意对 Content 联合的所有成员类型(在本例中为 Blog 和 Post)使用了内联片段。
query {
users {
name
content {
... on Blog {
title
}
... on Post {
content
}
}
}
}
如果查询中未包含对应于联合成员类型的内联片段,则不会返回该类型的任何字段。相反,响应将是一个空对象。
以下查询仅包含 Blog 类型的内联片段,而省略了 Post 类型的内联片段
query {
users {
name
content {
... on Blog {
title
}
}
}
}
此查询的响应中包含 Post 类型的空对象,因为查询中未为其指定任何字段
{
"data": {
"users": [
{
"name": "Alice",
"content": [{ "title": "Alice's Blog" }, {}]
},
{
"name": "Bob",
"content": [{}]
}
]
}
}
创建联合关系
要创建上图中显示的示例数据库数据,一种方法是先创建 User 节点。
User Alice 通过 HAS_CONTENT 关系连接到一个 Blog 节点,该 Blog 节点有两个通过 HAS_POST 关系连接的 Post 节点。对 Content 联合的关系可以通过嵌套变更(nested mutation)同时创建。
注意在 create 输入中指定了 Content 联合的具体类型(Blog)。
mutation {
createUsers(
input: [
{
name: "Bob"
},
{
name: "Alice"
content: {
Blog: {
create: [
{
node: {
title: "Our Blog"
posts: {
create: [
{ node: { content: "Alice's Post" } },
{ node: { content: "Bob's Post" } }
]
}
}
}
]
}
}
}
]
) {
users {
name
}
}
}
在空数据库上执行此变更将创建如下图形
更新联合关系
您可以更新 User 节点并创建它们与作为 Content 联合一部分的 Post 节点之间的 HAS_POST 关系。
注意在 update 输入中指定了 Content 联合的具体类型(Post)。
mutation {
mutation {
updateUsers(
where: { name: { eq: "Alice" } }
update: {
content: {
Post: [
{
connect: [
{
where: { node: { content: { eq: "Alice's Post" } } }
}
]
}
]
}
}
) {
users {
name
}
}
}
}
针对 User Bob 再次执行相同的变更,并调整过滤条件。