如何在 NestJs 框架中使用 postgres 和 sequelize 正确定义 DTO 对象

Posted

技术标签:

【中文标题】如何在 NestJs 框架中使用 postgres 和 sequelize 正确定义 DTO 对象【英文标题】:How to properly define DTO objects with postgres and sequelize in NestJs framework 【发布时间】:2021-06-28 07:52:40 【问题描述】:

我正在尝试在 NestJS 中创建简单的解析器,但类型有问题(我是打字稿的新手)。第二天我正在努力解决它,但我不明白。

我的 users.service.ts 有问题吗,有人可以检查我做错了什么吗?

// user.model.ts

import 
  BeforeCreate,
  Column,
  DataType,
  Model,
  PrimaryKey,
  Table,
 from 'sequelize-typescript';
import  Field, ID, ObjectType  from '@nestjs/graphql';

const argon2 = require('argon2');

@ObjectType()
@Table
export class User extends Model<User> 
  @Field()
  @Column( primaryKey: true, autoIncrement: true )
  id: number;

  @Field()
  @Column(
    type: DataType.STRING,
    allowNull: false,
  )
  firstName: string;

  @Field()
  @Column
  lastName: string;

  @Field()
  @Column
  username: string;

  @Field()
  @Column(
    type: DataType.STRING,
    allowNull: false,
  )
  password: string;

  @Field()
  @Column(
    type: DataType.STRING,
    unique: true,
    allowNull: false,
  )
  email: string;

  @Field()
  @Column( defaultValue: true )
  isActive: boolean;

  @BeforeCreate
  static async hashPassword(user: User) 
    if (user.password) 
      user.password = await argon2.hash(user.password);
    
  

// create-user.dto.ts

import  Field, InputType  from '@nestjs/graphql';

@InputType()
export class CreateUserDto 
  @Field()
  firstName?: string;

  @Field()
  username: string;

  @Field()
  email: string;

  @Field()
  lastName?: string;

  @Field()
  password: string;




// auth.resolver.ts

import 
  Resolver,
  Mutation,
  Args,
  Field,
  ObjectType,
  InputType,
 from '@nestjs/graphql';
import  IsString, IsEmail, IsNotEmpty  from 'class-validator';
import  AuthService  from './auth.service';
import  User  from '../users/user.model';
import  UsersService  from '../users/users.service';
import  Payload  from '../../types/payload';

@ObjectType()
export class AuthType 
  @Field()
  @IsEmail()
  email: string;
  @Field()
  @IsString()
  @IsNotEmpty()
  token: string;


@InputType()
export class UsernamePasswordInput 
  @Field()
  email: string;
  @Field()
  username: string;
  @Field()
  password: string;


@Resolver('Auth')
export class AuthResolver 
  constructor(
    private authService: AuthService,
    private userService: UsersService,
  ) 

  @Mutation((returns) => AuthType)
  async register(
    @Args('email') email: string,
    @Args('username') username: string,
    @Args('password') password: string,
  ) 
    const user: UsernamePasswordInput =  username, email, password ;
    try 
      const response: User = await this.userService.create(user);
      const payload: Payload = 
        email: response.email,
        username: response.username,
      ;

      const token = await this.authService.signPayload(payload);
      return  email: response.email, token ;
     catch (exception) 
      throw exception;
    
  

// users.service.ts

  async create(userDTO: CreateUserDto): Promise<User> 
    const  email  = userDTO;
    const user = await this.userModel.findOne( where:  email  );
    if (user) 
      throw new HttpException('User already exists', HttpStatus.BAD_REQUEST);
    
    // const createdUser = new this.userModel(userDTO);
    const createdUser = await this.userModel.create(userDTO);
    return await createdUser.save();
  

在 users.service.ts 行中: const createdUser = await this.userModel.create(userDTO);

我有错误:

(parameter) userDTO: CreateUserDto
Argument of type 'CreateUserDto' is not assignable to parameter of type 'User'.
  Type 'CreateUserDto' is missing the following properties from type 'User': isActive, $add, $set, $get, and 33 more.ts(2345)

【问题讨论】:

你可以使用类转换器 => github.com/typestack/class-transformer#plaintoclass。我从未使用过 sequelize-typescript 我个人使用 TypeORM,我使用 class-transformer 将我的 DTO 转换为实体 【参考方案1】:

我从模型定义中删除了:

export class User extends Model&lt;User&gt;

现在它可以工作了。

为什么在 Nest 文档中列出了这样一个奇怪的声明,我不知道.. 谢谢

【讨论】:

以上是关于如何在 NestJs 框架中使用 postgres 和 sequelize 正确定义 DTO 对象的主要内容,如果未能解决你的问题,请参考以下文章

Docker 中的 NestJS 无法在另一个 Docker 容器中的 Postgres 上执行 Prisma Migrate

存储 GeoJson 点并在给定距离/半径内查找点 | NODEJS、Postgres、NestJs、TypeOrm

如何在 NestJS 中提供静态图像

如何在 neo4j-graphql-js 端点中使用带有 nestjs 框架的拦截器?

AWS Lambda 上的 Nestjs(无服务器框架)|如何访问事件参数?

如何在带有 Postgres 的动态框架中使用窗口函数中的列值?