如何在node.js中的GraphQL中使InputType灵活?

时间:2016-04-08 11:30:17

标签: node.js graphql

关于使用Node.js实现GraphQL,我的问题很简单明了。

有两个突变。一个是createUser,另一个是updateUser。两个突变都有user参数UserInputType

const UserInputType = new GraphQLInputObjectType({
  name: 'UserInputType',
  description: 'a user input type',
  fields: () => {
    return {
      username: {
        type: GraphQLString,
        description: 'a unique username for a user',
      },
      email: {
        type: GraphQLString,
        description: 'a unique email for a user',
      },
      password: {
        type: GraphQLString,
        description: 'a strong password for a user',
      },
    };
  },
});

问题是,createUser突变需要所有参数用户名,电子邮件和密码。 updateUser只需要至少一个参数。我是否必须为每个突变实现两个UserInputType?我认为这不是好方法。

希望有一个线索!

1 个答案:

答案 0 :(得分:0)

调用突变时可以省略输入类型的字段。处理该变异的代码将为缺失的字段赋值undefined

如果createUserupdateUser所需的数据集相同,那么单个输入类型就可以。在这种情况下,是否必须检查客户端是否提供了所有参数createUser,这可以在以下示例代码中的mutateAndGetPayload函数中完成。另一种方法是让客户端检查(如果您编写客户端)。这种方法的优点是避免了相同字段的重复代码。

另一种方法是定义两个独立但大多数重复的类型。唯一的区别是updateUser的输入对象类型有GraphQLString,而createUser的其他对象类型有GraphQLNonNull(GraphQLString)。该方法具有避免检查空参数的优点。但是,我认为,在某些时候检查输入有效性是明智的。空值只是众多无效值中的一个。

按照第一种方法,我使用字段UserInputType扩展了您的id(通常用于更新操作以识别用户)并实施createUserMutationupdateUserMutation

在代码中,mutationWithClientMutationId是来自graphql-relay库的辅助函数。

const UserInputType = new GraphQLInputObjectType({
  name: 'UserInputType',
  description: 'a user input type',
  fields: {
      id: { type: GraphQLID },
      .....
      .....
  },
});

const createUserMutation = mutationWithClientMutationId({
  name: 'CreateUser',
  inputFields: {
    user: { type: UserInputType },
  },
  outputFields: {
    id: {
      type: GraphQLID,
      resolve: ({id}) => id,
    },
  },
  mutateAndGetPayload: ({user}) => {
    console.log('@ createUserMutation: Received user input:');
    console.log(`id: ${user.id}, username: ${user.username}, email: ${user.email}, password: ${user.password}`);
    if (hasValidInputs(user.username, user.email, user.password)) {
        return {id: '9999999'};
    } else {
        return {id: '-1'}
    }
  },
});

const updateUserMutation = mutationWithClientMutationId({
  name: 'UpdateUser',
  inputFields: {
    user: { type: UserInputType },
  },
  outputFields: {
    status: {
      type: GraphQLBoolean,
      resolve: ({status}) => status,
    },
  },
  mutateAndGetPayload: ({user}) => {
    console.log('@ updateUserMutation: Received user input:');
    console.log(`id: ${user.id}, username: ${user.username}, email: ${user.email}, password: ${user.password}`);
    return {status: true};
  },
});

使用express-graphql运行GraphQL服务器,updateMutation可以使用以下方法进行测试:

mutation {
  updateUser(input: {
    clientMutationId:"12344", 
    user: {
      username: "new username"
    }
  }) {
    clientMutationId,
    status,
  }
}

GraphQL服务器响应:

{
  "data": {
    "updateUser": {
      "clientMutationId": "12344",
      "status": true
    }
  }
}