你能将graphql类型设为输入和输出类型吗?

时间:2017-01-06 22:54:33

标签: graphql graphql-js

我有一些我想用作输入和输出的对象类型 - 例如货币类型或预订类型。

如何定义我的架构以使其具有支持输入和输出的类型 - 如果我不需要,我不想重复代码。我也不想创建像货币和状态枚举这样的重复输入类型。

export const ReservationInputType = new InputObjectType({
  name: 'Reservation',
  fields: {
    hotelId: { type: IntType },
    rooms: { type: new List(RoomType) },
    totalCost: { type: new NonNull(CurrencyType) },
    status: { type: new NonNull(ReservationStatusType) },
  },
});

export const ReservationType = new ObjectType({
  name: 'Reservation',
  fields: {
    hotelId: { type: IntType },
    rooms: { type: new List(RoomType) },
    totalCost: { type: new NonNull(CurrencyType) },
    status: { type: new NonNull(ReservationStatusType) },
  },
});

4 个答案:

答案 0 :(得分:14)

在GraphQL规范中,对象和输入对象是不同的东西。引用the spec for input objects

  

字段可以定义客户端使用查询传递的参数,以配置其行为。这些输入可以是字符串或枚举,但它们有时需要比这更复杂。

     

对象类型...不适合在此处重复使用,因为对象可以包含表示循环引用或对接口和联合的引用的字段,这两个字段都不适合用作输入参数。因此,输入对象在系统中具有单独的类型。

     

输入对象定义一组输入字段;输入字段是标量,枚举或其他输入对象。这允许参数接受任意复杂的结构。

虽然实现可能提供方便代码来从单个定义创建对象和相应的输入对象,但是在规则下,规范表明它们必须是单独的东西(具有单独的名称,例如{{1 }和Reservation)。

答案 1 :(得分:2)

您可以这样做:



export const createTypes = ({name, fields}) => {
  return {
    inputType: new InputObjectType({name: `${name}InputType`, fields}),
    objectType: new ObjectType({name: `${name}ObjectType`, fields})
  };
};

const reservation = createTypes({
  name: "Reservation",
  fields: () => ({
    hotelId: { type: IntType },
    rooms: { type: new List(RoomType) },
    totalCost: { type: new NonNull(CurrencyType) },
    status: { type: new NonNull(ReservationStatusType) }
  })
});
// now you can use:
//  reservation.inputType
//  reservation.objectType




答案 2 :(得分:2)

在处理项目时,我在inputtype对象之间进行代码复制时遇到了类似的问题。我发现extend关键字不是很有帮助,因为它仅扩展了该特定类型的字段。因此,不能在type对象中继承input对象中的字段。

最后,我发现使用文字表达式的这种模式很有帮助:

const UserType = `
    name: String!,
    surname: String!
`;

const schema = graphql.buildSchema(`
    type User {
        ${UserType}
    }
    input InputUser {
        ${UserType}
    }
`) 

答案 3 :(得分:1)

这是我为我的项目所做的(效果很好):

const RelativeTemplate = name => {
  return {
    name: name,
    fields: () => ({
      name: { type: GraphQLString },
      reference: { type: GraphQLString }
    })
  };
};
const RelativeType = {
  input: new GraphQLInputObjectType(RelativeTemplate("RelativeInput")),
  output: new GraphQLObjectType(RelativeTemplate("RelativeOutput"))
};