interface - GraphQL 接口(interface) : [interface] expects "fieldname" but [type] does not provide it

标签 interface graphql graphql-js

我有以下原因。我调用多个 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
});

但是,我想制作一个界面,因为我一遍又一遍地使用所有这些字段。我不想重复自己。

我正在尝试实现一个接口(interface)(以 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,
});

最佳答案

扩展一个接口(interface)基本上就是说“这个类型将包含这些字段”并且 GraphQL 将在编译您的模式时强制执行该规则。不幸的是,这些字段仍然必须为扩展接口(interface)的每种类型显式定义——GraphQL 中没有类型继承。

如果您想避免重复自己,唯一可以做的就是利用您的字段定义只返回一个对象这一事实:

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 .

关于interface - GraphQL 接口(interface) : [interface] expects "fieldname" but [type] does not provide it,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48518227/

相关文章:

c# - 当一个接口(interface)从另一个接口(interface) "inherits"时,你怎么调用它?

reactjs - 初始化后更新 ApolloClient header

graphql - buildSchema和GraphQLSchema之间的显着差异?

go - 如何修改未知类型的结构中的字段?

c++ - 通用 API 发布技术

javascript - 将参数从 React-router 传递到 Apollo Client 2.1 中的查询组件

javascript - 编译时出现 graphQL 错误

graphql - 无法自定义 graphql 枚举的值

graphql - 如何在 GraphQL 中查询以数组作为参数的对象列表

delphi - 多个接口(interface),Supports() 函数和引用计数