GraphQL 接口:[interface] 需要 "fieldname" 但 [type] 没有提供
GraphQL Interface: [interface] expects "fieldname" but [type] does not provide it
我有以下原因。我调用了多个 API 的网上商店。每个网上商店都有自己的 GraphQLObjectType,如下面的代码所示。
我目前的类型代码:
// Amazon
const AmazonType = new GraphQLObjectType({
name: 'amazon',
fields: () => ( {
isbn: { type : GraphQLString},
title: { type: GraphQLString },
author: { type: GraphQLString},
publisher: { type: GraphQLString},
})
});
// itunes
const ItunesType = new GraphQLObjectType({
name: 'itunes',
fields: () => ( {
isbn: { type: GraphQLString },
title: { type: GraphQLString },
author: { type: GraphQLString },
publisher: { type: GraphQLString },
})
});
// query
const checkStores = new GraphQLObjectType({
name:'checkBookInStores',
fields: () => ( {
isbn: {
type: GraphQLString,
},
itunes: {
type: ItunesType,
resolve(parentValue,args){
//console.log(parentValue);
data = itunes.getMetadataItunes(parentValue.isbn);
return data;
}
},
amazon: {
type: AmazonType,
resolve(parentValue, args) {
//console.log(parentValue);
data = amazon.getMetadataAmazon(parentValue.isbn);
return data;
}
},
})
});
//RootQuery
const RootQuery = new GraphQLObjectType({
name:'RootQuery',
fields:() =>( {
checkStores: {
type: new GraphQLList(checkStores),
args: {
id: { type: new GraphQLList(GraphQLString),
},
resolve: function (_, {id}) {
var data = [];
for(var i = 0; i < id.length; i++){
var record = {
"isbn": id[i],
};
data.push(record);
}
return data;
}
}
})
});
//schema
module.exports = new GraphQLSchema({
query: RootQuery
});
但是,我想制作一个界面,因为我一遍又一遍地使用所有这些字段。我不想重复自己。
我正在尝试实现一个接口(以 issue 为例),但出现以下错误:
"Error: \"metadata\" expects field \"isbn\" but \"itunes\" does not
provide it.",
新密码:
// interface
const MetadataType = new GraphQLInterfaceType({
name: 'metadata',
fields: () => ({
isbn: { type: GraphQLString },
title: { type: GraphQLString },
author: { type: GraphQLString },
publisher: { type: GraphQLString },
}),
resolveType: (value) => {
console.log('value resolvetype:', value)
if (value instanceof ItunesType) {
return ItunesType;
}
else {
return null;
}
},
});
// itunes
const ItunesType = new GraphQLObjectType({
name: 'itunes',
interfaces: [MetadataType],
fields: () => ({
name: { type: GraphQLString}
}),
isTypeOf: (value) => value instanceof ItunesType,
});
扩展一个接口基本上就是 "this Type will contain these fields" 并且 GraphQL 将在编译您的模式时强制执行该规则。不幸的是,这些字段仍然必须为扩展接口的每种类型显式定义——GraphQL 中没有类型继承。
如果您想避免重复自己,唯一可以做的就是利用您的字段定义只是 return 一个对象这一事实:
const commonFields = {
isbn: { type: GraphQLString },
title: { type: GraphQLString },
author: { type: GraphQLString },
publisher: { type: GraphQLString },
};
const AmazonType = new GraphQLObjectType({
name: 'amazon',
fields: () => commonFields,
});
const ItunesType = new GraphQLObjectType({
name: 'itunes',
fields: () => commonFields,
});
如果您有特定于单一类型的附加字段,您还可以执行以下操作:
Object.assign({
amazonOnlyField: { type: GraphQLString },
}, commonFields)
最后,如果你真的想要类型继承,你可以考虑使用补充库like GraphQL S2S。
我有以下原因。我调用了多个 API 的网上商店。每个网上商店都有自己的 GraphQLObjectType,如下面的代码所示。
我目前的类型代码:
// Amazon
const AmazonType = new GraphQLObjectType({
name: 'amazon',
fields: () => ( {
isbn: { type : GraphQLString},
title: { type: GraphQLString },
author: { type: GraphQLString},
publisher: { type: GraphQLString},
})
});
// itunes
const ItunesType = new GraphQLObjectType({
name: 'itunes',
fields: () => ( {
isbn: { type: GraphQLString },
title: { type: GraphQLString },
author: { type: GraphQLString },
publisher: { type: GraphQLString },
})
});
// query
const checkStores = new GraphQLObjectType({
name:'checkBookInStores',
fields: () => ( {
isbn: {
type: GraphQLString,
},
itunes: {
type: ItunesType,
resolve(parentValue,args){
//console.log(parentValue);
data = itunes.getMetadataItunes(parentValue.isbn);
return data;
}
},
amazon: {
type: AmazonType,
resolve(parentValue, args) {
//console.log(parentValue);
data = amazon.getMetadataAmazon(parentValue.isbn);
return data;
}
},
})
});
//RootQuery
const RootQuery = new GraphQLObjectType({
name:'RootQuery',
fields:() =>( {
checkStores: {
type: new GraphQLList(checkStores),
args: {
id: { type: new GraphQLList(GraphQLString),
},
resolve: function (_, {id}) {
var data = [];
for(var i = 0; i < id.length; i++){
var record = {
"isbn": id[i],
};
data.push(record);
}
return data;
}
}
})
});
//schema
module.exports = new GraphQLSchema({
query: RootQuery
});
但是,我想制作一个界面,因为我一遍又一遍地使用所有这些字段。我不想重复自己。
我正在尝试实现一个接口(以 issue 为例),但出现以下错误:
"Error: \"metadata\" expects field \"isbn\" but \"itunes\" does not provide it.",
新密码:
// interface
const MetadataType = new GraphQLInterfaceType({
name: 'metadata',
fields: () => ({
isbn: { type: GraphQLString },
title: { type: GraphQLString },
author: { type: GraphQLString },
publisher: { type: GraphQLString },
}),
resolveType: (value) => {
console.log('value resolvetype:', value)
if (value instanceof ItunesType) {
return ItunesType;
}
else {
return null;
}
},
});
// itunes
const ItunesType = new GraphQLObjectType({
name: 'itunes',
interfaces: [MetadataType],
fields: () => ({
name: { type: GraphQLString}
}),
isTypeOf: (value) => value instanceof ItunesType,
});
扩展一个接口基本上就是 "this Type will contain these fields" 并且 GraphQL 将在编译您的模式时强制执行该规则。不幸的是,这些字段仍然必须为扩展接口的每种类型显式定义——GraphQL 中没有类型继承。
如果您想避免重复自己,唯一可以做的就是利用您的字段定义只是 return 一个对象这一事实:
const commonFields = {
isbn: { type: GraphQLString },
title: { type: GraphQLString },
author: { type: GraphQLString },
publisher: { type: GraphQLString },
};
const AmazonType = new GraphQLObjectType({
name: 'amazon',
fields: () => commonFields,
});
const ItunesType = new GraphQLObjectType({
name: 'itunes',
fields: () => commonFields,
});
如果您有特定于单一类型的附加字段,您还可以执行以下操作:
Object.assign({
amazonOnlyField: { type: GraphQLString },
}, commonFields)
最后,如果你真的想要类型继承,你可以考虑使用补充库like GraphQL S2S。