GraphQL接口:[interface]需要“fieldname”但[type]不提供它

时间:2018-01-30 09:40:28

标签: interface graphql graphql-js

我有以下casus。我打电话给多个API的网络商店。每个webstore都有自己的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
});

但是,我想创建一个接口,因为我使用所有那些fieldsover并重复使用。我不想重复自己。

我正在尝试实现一个接口(通过查看此issue作为示例)但是我收到以下错误:

  

“错误:\”metadata \“期望字段\”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,
});

1 个答案:

答案 0 :(得分:1)

扩展接口基本上说&#34;此类型将包含这些字段&#34;和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