ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • nestJS entity
    Project using Nest.js/E-commerce App 2021. 9. 2. 12:33

    common.entity.ts

    import { Field, ObjectType } from '@nestjs/graphql';
    import {
      CreateDateColumn,
      PrimaryGeneratedColumn,
      UpdateDateColumn,
    } from 'typeorm';
    
    @ObjectType()
    export class CoreEntity {
      @PrimaryGeneratedColumn()
      @Field((type) => Number)
      id: number;
    
      @CreateDateColumn()
      @Field((type) => Date)
      createdAt: Date;
    
      @UpdateDateColumn()
      @Field((type) => Date)
      updatedAt: Date;
    }

    user.entity.ts

    import {
      Field,
      InputType,
      ObjectType,
      registerEnumType,
    } from '@nestjs/graphql';
    import { IsBoolean, IsEmail, IsEnum, IsString } from 'class-validator';
    import { BeforeInsert, Column, Entity } from 'typeorm';
    import * as bcrypt from 'bcrypt';
    
    import { CoreEntity } from 'src/common/entities/common.entity';
    import { InternalServerErrorException } from '@nestjs/common';
    
    export enum UserRole {
      Consumer = 'Consumer',
      Provider = 'Provider',
    }
    
    enum Language {
      Korean = 'Korean',
      English = 'English',
    }
    
    registerEnumType(UserRole, { name: 'UserRole' });
    registerEnumType(Language, { name: 'Language' });
    
    @InputType('UserInputType', { isAbstract: true })
    @ObjectType()
    @Entity()
    export class User extends CoreEntity {
      @Column({ unique: true })
      @Field((type) => String)
      @IsEmail()
      email: string;
    
      @Column()
      @Field((type) => String)
      @IsString()
      password: string;
    
      @Column({ type: 'enum', enum: UserRole, default: UserRole.Consumer })
      @Field((type) => UserRole)
      @IsEnum(UserRole)
      role: UserRole;
    
      @Column({ default: false })
      @Field((type) => Boolean)
      @IsBoolean()
      verified: boolean;
    
      @Column({ default: Language.Korean })
      @Field((type) => Language)
      @IsEnum(Language)
      language: Language;
    
      @Column({ nullable: true })
      @Field((type) => String, { nullable: true })
      @IsString()
      bio?: string;
      
       @BeforeInsert()
      async hashPassword(): Promise<void> {
        if (this.password) {
          try {
            this.password = await bcrypt.hash(this.password, 10);
          } catch (e) {
            console.error(e);
            throw new InternalServerErrorException();
          }
        }
      }
    
      async checkPassowrd(password: string): Promise<boolean> {
        try {
          const ok = await bcrypt.compare(password, this.password);
          return ok;
        } catch (error) {
          console.error(error);
          throw new InternalServerErrorException();
        }
      }  
    }

     

    • @Column()은 TypeORM의 Schema로 정의하는 decorator다. @Column()을 하고 밑에 field를 정의하면 db field에 등록된다.
    • @Field()는 graphql의 type을 정의한다.
    • @IsEmail(), @IsString() 등은 class-validator로 유효성 검사를 한다.
    • enum type은 registerEnumType(UserRole, { name: 'UserRole' });를 사용하여서 등록해서 쓸 수 있다.

     

    • entity 안에 method를 선언할 수 있다. ex) checkPassword
    • @BeforeInsert() decorator를 이용해서 데이터가 db에 저장되기 이전에 process 할 수 있다.
    • await bcrypt.hash() function이 있는데, password는 저장되기 전에 무조건 해시를 한 후 저장해야 한다.
      • Installation : $ npm i bcrypt

    Validation

       Entity에서 @IsEmail()같이 validate를 하는 decorator가 있다.

      $ npm i class-transformer class-validator

    두 개 모듈을 설치함으로써 사용할 수 있다. 그리고 app.useGlobalPipes(new ValidationPipe());를 추가한다.

    참고 자료

    댓글

Designed by Tistory.