对于带有 bcrypt 的 typegraphql 中的不可空字段 Mutation.create 不能 return null

Cannot return null for non-nullable field Mutation.create in typegraphql with bcrypt

我正在尝试使用 apollo-server、typeorm、bcrypt 和 typescript 中的以下解析器来使用 typegraphql。当突变查询为 运行 时,它会抛出错误 'Cannot return null for non-nullable field Mutation.create'。但是它使用散列密码将数据保存到数据库中(我也可以使用 console.log 肯定地推断出这一点);只有突变查询在浏览器中抛出错误。

这里是突变解析器:

@Mutation(returns => Users)
create(@Arg("newuser") newuser: UserInput): Promise<Users> | any {
  bcrypt.hash(newuser.loginpassword, 12)
  .then( hash => {
      const new_user = this.usersRepository.create(newuser);
      new_user.loginpassword = hash;
      return this.usersRepository.save(new_user);
    });
}

同样,当 bcrypt 相关内容被注释掉时,return没有错误(当然密码没有被散列)

@Mutation(returns => Users)
create(@Arg("newuser") newuser: UserInput): Promise<Users> | any {
  // bcrypt.hash(newuser.loginpassword, 12)
  // .then( hash => {
      const new_user = this.usersRepository.create(newuser);
      //new_user.loginpassword = hash;
      return this.usersRepository.save(new_user);
    //});
}

在这两种情况下,突变都能够创建记录并保存它们;还使用 bcrypt 代码成功生成哈希。

过去 2 周我一直在努力解决这个问题,在这里( 和许多类似的地方)搜索解决这个问题的线索。

  1. 第一个版本有什么问题(包括 bcrypt 代码)我试过将 return 类型更改为 Users |任何来自 Promise |任何,再添加一个 .then 语句 return 用户对象而不是承诺对象?

  2. 同样在中,Benjie先生在暗示https://www.graphile.org/postgraphile/why-nullable/#nulls-in- graphql.但是我完全不知道如何写nullable Mutation.create。有人可以暗示或指出一个例子或这样的模式吗?

  3. 如果我将 create 的 return 声明保留为 'Promise<Users>' 而不是 'Promise<Users> | any',则打字稿不满意并期待 return 语句。但是如果我在末尾添加 return 语句,create 将立即 return 。那么,return 声明为 'Promise<Users> | any' 是正确的方法吗?

谢谢大家

我不是很确定,但我看到了一些可能导致此问题的原因。

  1. 在您的第一个代码片段中,唯一的 return 语句位于传递给 then 的回调函数中。所以 create 方法没有 return 任何东西。

  2. 我查看了 typeORM 的 src...当输入时它看起来像 Repository.save() returns Promise<Entity>(不是 Promise<Entity[]>)值是单个实体对象 (see Repository.ts)。如果是这种情况,您的 GraphQL 架构将期望此突变为 return 一组用户,但解析器是 return 单个用户。

尝试将 return 类型更改为 Promise<User>

@Mutation(returns => User)
create(@Arg("newuser") newuser: UserInput): Promise<User> {
  return bcrypt.hash(newuser.loginpassword, 12)
  .then( hash => {
      const new_user = this.usersRepository.create(newuser);
      new_user.loginpassword = hash;
      return this.usersRepository.save(new_user);
    });
}