GraphQL类型组合

时间:2017-05-08 16:08:33

标签: design-patterns graphql graphql-js apollo

我正在探索graphql,令我不安的问题是,在定义我的graphql服务器时,我是否可以做某种类型的组合。

我们假设我的收藏中有人和公司。我有这样的事情:

const Person = new GraphQLObjectType({
  name: 'Person',
  fields: {
    firstName: {type: GraphQLString},
    lastName: {type: GraphQLString}
  }
});

const Company = new GraphQLObjectType({
  name: 'Company',
  fields: {
    name: {type: GraphQLString},
    website: {type: GraphQLString}
  }
});

但公司和个人都应包含以下字段:createdAtid。假设我有:

const Entity = new GraphQLObjectType({
  name: 'Entity',
  fields: {
    id: {type: GraphQLString},
    createdAt: {type: GraphQLString}
  }
});

所以我想的是:

new GraphQLObjectType({
  ...
  extends: [Entity]
});

我知道有interfaces但我认为它不是我想要的,因为那时我需要实现接口而我想要实现的是保持一些字段定义并重新使用它们与其他类型有关。

有什么想法吗?我试图做一些毫无意义的事情吗?

2 个答案:

答案 0 :(得分:0)

如果我们看一下GraphQL语言规范,就有接口。接口用于描述两种类型的常见行为。如果在同一个字段中返回两个子类型,接口通常才有意义。 GraphQL documentation有一个很好的例子。我建议不要在你的情况下使用接口,除非你想在同一个字段中返回所有实体类型(比如在搜索中)。

您正在谈论服务器实施级别。我不知道在GraphQL.js中扩展这样的类型。你可以做的是创建一个包含两个字段的JavaScript对象。然后,您可以重复使用此代码并将其插入到每个类型中,例如使用Object.assign

  const standardFields = {
    id: {
      type: new GraphQLNonNull(GraphQLID),
      description: 'Unique id for this entity'
    },
    createdAt: {
      type: new GraphQLNonNull(GraphQLString),
      description: 'Datetime of this entity\'s creation'
    }
  }

  const Company = new GraphQLObjectType({
    name: 'Company',
    fields: Object.assign({}, standardFields, {
      name: {type: GraphQLString},
      website: {type: GraphQLString}
    }
  });

或者可以从文件中导入字段并明确插入:

  const { id, createdAt } = require('./standardFields');

  const Company = new GraphQLObjectType({
    name: 'Company',
    fields: {
      id,
      createdAt,
      name: {type: GraphQLString},
      website: {type: GraphQLString}
    }
  });

在这两种情况下,我都没有从中获益。设置一个确保所有类型都包含字段的测试可能更有用。

答案 1 :(得分:0)

您可以从interface类型获取字段:

const carInterface = new GraphQLInterfaceType({
  name: 'car',
  fields: {
    _id: { type: GraphQLID },
    userId: { type: GraphQLID },
    carType: { type: new GraphQLNonNull(GraphQLString), description: 'نوع اعلان السيارة' },
    title: { type: new GraphQLNonNull(GraphQLString), description: 'عنوان الاعلان' },
    brand: { type: GraphQLString, description: 'الماركة-النوع' },
    model: { type: GraphQLString, description: 'الموديل' }
   }
});
console.log(carInterface._typeConfig.fields);

您可以轻松地将carInterface._typeConfig.fields添加到任何GraphQLObject字段定义;