如果所提供的类型都不匹配,我正在尝试在resolveType
函数中返回泛型类型。下面的示例显示了此问题:API在支持UserType
和MovieType
的情况下工作,直到添加数据库BookType
(GraphQL架构不支持)。
const {
graphql,
GraphQLSchema,
GraphQLObjectType,
GraphQLString,
GraphQLNonNull,
GraphQLList,
GraphQLInterfaceType
} = require("graphql");
const DATA = [
{
// UserType
name: "catherine woolf",
nick: "catherine"
},
{
// MovieType
name: "cat woman",
director: "Jack Wolfgang"
},
{
// --- missing type --- (BookType)
name: "cats secrets",
author: "Nicky Glace"
}
];
const resolveType = data => {
if (data.nick) {
return UserType;
}
if (data.director) {
return MovieType;
}
};
const SearchableType = new GraphQLInterfaceType({
name: "Searchable",
fields: {
name: { type: GraphQLString }
},
resolveType: resolveType
});
const UserType = new GraphQLObjectType({
name: "User",
interfaces: [SearchableType],
fields: {
name: { type: GraphQLString },
nick: { type: GraphQLString }
}
});
const MovieType = new GraphQLObjectType({
name: "Movie",
interfaces: [SearchableType],
fields: {
name: { type: GraphQLString },
director: { type: GraphQLString }
}
});
const schema = new GraphQLSchema({
types: [MovieType, UserType, SearchableType],
query: new GraphQLObjectType({
name: "RootQueryType",
fields: {
search: {
type: new GraphQLList(SearchableType),
args: {
text: { type: new GraphQLNonNull(GraphQLString) }
},
resolve(_, { text }) {
return DATA.filter(d => d.name.indexOf(text) !== -1);
}
}
}
})
});
const query = `
{
search(text: "cat") {
name
... on User {
nick
}
... on Movie {
director
}
}
}
`;
graphql(schema, query).then(result => {
console.log(JSON.stringify(result, null, 2));
});
所以现在这段代码以错误结束:
“抽象类型Searchable必须在运行时为字段RootQueryType.search解析为Object类型,其值为”[object Object] \“,收到”undefined“。或者Searchable类型应该提供一个”resolveType“函数或每种可能的类型应该提供一个“isTypeOf”函数。“
这并不奇怪,因为目前resolveType
可能不会返回任何类型。
包含相同字段的Crate类型,如接口SearchableType
(1对1实现):
const _SearchableType = new GraphQLObjectType({
name: '_Searchable',
interfaces: [SearchableType],
fields: {
name: { type: GraphQLString },
}
});
将其用作后备类型:
const resolveType = data => {
if (data.nick) {
return UserType;
}
if (data.director) {
return MovieType;
}
return _SearchableType;
};
并将其添加到types
定义中的schema
:
types: [MovieType, UserType, SearchableType, _SearchableType],
但是这个解决方案的问题是在这样的文档中存在这个虚拟_SearchableType
:
有没有办法在SearchableType
中返回接口resolveType
或其等价物?对我而言,关键是在文档中隐藏这种“后备类型”。
答案 0 :(得分:1)
GraphQL是强类型的,并不支持泛型或某种"后备"解析联合和接口时的机制。在一天结束时,如果您的基础数据层返回了某些尚未在架构中实现的类型,那么最简单的解决方案就是将该类型添加到架构中。迁移到您的数据库和模式的更改应该齐头并进。
如果您想从存储层派生架构,我建议您查看类似PostGraphile(以前的PostGraphQL)的内容。
也就是说,如果您一直在尝试使用解决方法,那么您可以回退到现有类型之一:
const resolveType = data => {
if (data.nick) {
return UserType
}
return MovieType
}
现在,只要您在界面上查询并且不是其中一种类型,书籍的名称仍然可以访问。这种方法的唯一缺点是,将为一本书返回特定于电影的字段并将其解析为null,但这不会导致任何问题,除非它们在模式中被特别定义为非null。