![](/img/trans.png)
[英]Graphql resolveType union: throwing must resolve to an object type at runtime
[英]GraphQL.js - use Interface as a default (fallback) type in resolveType function
如果提供的類型都不匹配,我試圖在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] \\”,接收為\\“ undefined \\”。Searchable類型應提供一個\\“ resolveType \\”函數,或者每個可能的類型應提供\\“ isTypeOf \\”函數。
這不足為奇,因為當前resolveType
可能不返回任何類型。
板條箱類型包含相同的字段,例如接口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;
};
並將其添加到schema
定義中的types
:
types: [MovieType, UserType, SearchableType, _SearchableType],
但是此解決方案的問題是這樣的偽_SearchableType
在如下文檔中的存在:
有什么方法可以返回接口SearchableType
或resolveType
等效接口嗎? 對我而言,關鍵點是在文檔中隱藏了這種“后備類型”。
GraphQL是強類型的,在解決聯合和接口時不支持泛型或某種“后備”機制。 歸根結底,如果您的基礎數據層返回的是您尚未在架構中實現的某種類型,那么最簡單的解決方案是將該類型添加到架構中。 遷移到數據庫和更改架構應該同時進行。
如果要從存儲層派生架構,建議您使用PostGraphile (以前稱為PostGraphQL)之類的工具。
就是說,如果您打算使用一種解決方法,則可以使用現有類型之一:
const resolveType = data => {
if (data.nick) {
return UserType
}
return MovieType
}
現在,只要您在界面(而不是其中一種類型)上進行查詢,一本書的名稱仍然可以訪問。 這種方法的唯一缺點是,將為書籍返回特定於電影的字段,並將其解析為null,但這不會引起任何問題,除非在您的模式中將它們明確定義為非null。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.