【问题标题】:GraphQL Interface: [interface] expects "fieldname" but [type] does not provide itGraphQL 接口:[interface] 需要“fieldname”,但 [type] 没有提供它
【发布时间】:2018-01-30 20:24:08
【问题描述】:

我有以下理由。我调用多个 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 为例),但出现以下错误:

“错误:\”元数据\”需要字段\“isbn\”,但\“itunes\”没有 提供它。",

新代码:

// 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 graphql-js


    【解决方案1】:

    扩展接口基本上说“此类型将包含这些字段”,GraphQL 将在编译架构时强制执行该规则。不幸的是,仍然必须为扩展接口的每个类型显式定义这些字段——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

    【讨论】:

    • 感谢您的回答并深入示例。 :) 我去图书馆看看。
    猜你喜欢
    • 2015-11-23
    • 2020-06-23
    • 2019-05-18
    • 2020-08-24
    • 2021-12-03
    • 1970-01-01
    • 2020-10-18
    • 2012-07-07
    • 2014-04-15
    相关资源
    最近更新 更多