我很难理解何时使用GraphQLInterfaceType
和GraphQLUnionType
.
我有RTFM:
http://graphql.org/docs/api-reference-type-system/#graphqluniontype
https://github.com/mugli/learning-graphql/blob/master/7.%20Deep%20Dive%20into%20GraphQL%20Type%20System.md
任何人都可以提供一个真实世界的例子,当这些通过我的厚头有用时会有用吗?
两者都旨在帮助您设计具有异构类型集的模式,并且您可以使用两者来实现相同的功能,但是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
函数中访问单个字段.