Mat*_*t K 15 graphql graphql-js
我很难理解何时使用GraphQLInterfaceType和GraphQLUnionType.
我有RTFM:
任何人都可以提供一个真实世界的例子,当这些通过我的厚头有用时会有用吗?
Jes*_*era 28
两者都旨在帮助您设计具有异构类型集的模式,并且您可以使用两者来实现相同的功能,但是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;
}
Run Code Online (Sandbox Code Playgroud)
当我们创建一个新的博客发送时username,它将创建一个BlogA.
我们可以像这样查询:
query MyQuery {
blogs: {
url
password
... on BlogA {
email
}
... on BlogB {
username
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在让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;
}
Run Code Online (Sandbox Code Playgroud)
我们可以像这样查询:
query MyQuery {
blogs: {
url
auth {
... on AuthA {
username
password
}
... on AuthB {
email
password
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如您在本示例中所看到的,我们使用接口或union实现了相同的功能,但根据您的架构设计,其中一个可能更合适.
例如,假设您要添加一个也使用电子邮件和密码的博客框架C. 您需要包含另一个字段才能将其与我们resolveBlogType函数中的博客框架B区分开来.让我们添加type字段.在我们的Union示例中,由于我们只能访问Union中的字段,因此您可以添加type到Union.如果将来我们想为多个框架添加另一个具有相同字段的Union,我们还需要在type那里添加字段.type在我们的架构中多次重复不太好.使用接口可能是一个更好的主意,并且所有使用接口的对象都type可以在resolveBlogType函数中访问单个字段.
小智 2
的语义GraphQLInterfaceType与大多数程序语言的语义相似interface。graphql 为其添加了更多行为。比如检查派生类是否实现了所有字段,动态解析为派生实例。
的语义GraphQLUnionType不是 a Union,而是类似OR. (有点像 flowtype 的类型检查?)
现实世界的示例是Relay => Relay's Node design 中的示例。
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
}
Run Code Online (Sandbox Code Playgroud)
如果对此感到困惑,你应该读一些强类型语言的书。(比如 C# 或 Java 或其他东西。也许你也应该看看 Flow,这种用法Dog|Cat是类型限制)
| 归档时间: |
|
| 查看次数: |
6613 次 |
| 最近记录: |