我很难理解何时使用GraphQLInterfaceType
和GraphQLUnionType
。
我有RTFM:
任何人都可以提供一个真实世界的例子,当这些有用的时候可以让我通过我的头脑吗?
答案 0 :(得分:26)
两者都旨在帮助您设计具有异构类型集的模式,并且您可以使用两者来实现相同的功能,但GraphQLInterfaceType
更适合于类型基本相同但某些字段是不同的,GraphQLUnionType
当类型完全不同并且具有完全不同的字段时。
最终是否根据您的架构设计使用其中一个。
对于一个真实的例子,让我们说你有一个博客列表,但使用框架A的博客使用用户名和密码作为身份验证,而使用框架B的博客使用电子邮件和密码。我们用这样的GraphQLInterfaceType
设计它:
const BlogType = new GraphQLInterfaceType({
name: 'Blog',
fields: {
url: { type: new GraphQLNonNull(GraphQLString) }
password: { type: new GraphQLNonNull(GraphQLString) }
},
resolveType: resolveBlogType
});
const BlogAType = new GraphQLObjectType({
name: 'BlogA',
interfaces: [Blog],
fields: {
url: { type: new GraphQLNonNull(GraphQLString) }
username: { type: new GraphQLNonNull(GraphQLString) },
password: { type: new GraphQLNonNull(GraphQLString) }
}
});
const BlogBType = new GraphQLObjectType({
name: 'BlogB',
interfaces: [Blog],
fields: {
url: { type: new GraphQLNonNull(GraphQLString) }
email: { type: new GraphQLNonNull(GraphQLString) },
password: { type: new GraphQLNonNull(GraphQLString) }
}
});
function resolveBlogType(value) {
return value.username ? BlogAType : BlogBType;
}
当我们创建发送username
的新博客时,它会创建BlogA
。
我们可以像这样查询:
query MyQuery {
blogs: {
url
password
... on BlogA {
email
}
... on BlogB {
username
}
}
}
现在让我们使用GraphQLUnionType
获得相同的功能,因为我们更喜欢使用一种类型的博客,以及两种类型的身份验证方法:
const AuthAType = new GraphQLObjectType({
name: 'AuthA',
fields: {
username: { type: new GraphQLNonNull(GraphQLString) },
password: { type: new GraphQLNonNull(GraphQLString) }
}
});
const AuthBType = new GraphQLObjectType({
name: 'AuthB',
fields: {
email: { type: new GraphQLNonNull(GraphQLString) },
password: { type: new GraphQLNonNull(GraphQLString) }
}
});
const AuthType = new GraphQLUnionType({
name: 'Auth',
types: [AuthAType, AuthBType]
resolveType: resolveAuthType
});
const BlogType = new GraphQLInterfaceType({
name: 'Blog',
fields: {
url: { type: new GraphQLNonNull(GraphQLString) }
auth: { type: AuthType }
},
});
function resolveAuthType(value) {
return value.username ? AuthAType : AuthBType;
}
我们可以像这样查询:
query MyQuery {
blogs: {
url
auth {
... on AuthA {
username
password
}
... on AuthB {
email
password
}
}
}
}
正如您在本示例中所看到的,我们使用接口或union实现了相同的功能,但根据您的架构设计,其中一个可能更合适。
例如,假设您要添加一个也使用电子邮件和密码的博客框架C.您需要包含另一个字段,以便能够在我们的resolveBlogType
函数中将其与博客框架B区分开来。我们添加type
字段。在我们的Union示例中,由于我们只能访问Union中的字段,因此您可以将type
添加到Union。如果将来我们想为多个框架添加另一个具有相同字段的Union,我们还需要在那里添加type
字段。在我们的架构中多次重复type
不太好。使用接口可能是一个更好的主意,并且所有使用接口的对象都可以在type
函数访问单个resolveBlogType
字段。
答案 1 :(得分:2)
GraphQLInterfaceType
的抒情诗就像大多数程序语言interface
一样。和graphql为它添加一些更多的行为。比如检查派生类是否实现了所有字段,动态解析为派生实例
GraphQLUnionType
的抒情诗不是Union
,而是OR
。(有点像flowtype的类型检查?)
一个真实的例子是example in Relay =>继电器的节点设计。
GraphQLInterfaceType
与GraphQLUnionType
完全无关
我想也许你对此感到困惑?
interface Node{
id: string
}
type Dog implements Node{
id: string
}
type Cat implements Node{
id: string
}
union Animal = Dog | Cat
type User{
node: Node
animal: Animal
}
如果对此感到困惑,你应该阅读一些强类型语言的书。(比如C#或Java或其他东西。也许你应该看一下Flow,这种用法Dog|Cat
是一种类型限制)