-
nestJS entityProject 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(); } } }
- @Entity() decorator는 entity를 정의할 수 있게 해준다. 그 안에 email, password 등의 필드들을 정의할 수 있다. TypeORM을 위한 코드다.
ref : https://docs.nestjs.com/techniques/database#repository-pattern - @ObjectType() decorator는 Graphql을 위한 코드다.
ref : https://docs.nestjs.com/graphql/resolvers#object-types - @InputType()는 DTOs를 위한 코드다. mapped types를 위해서 @InputType()을 해줘야 한다. 그리고 InputType에 'UserInputType'이라고 이름을 지정해줘야 한다. 그렇지 않으면 나중에 reloation field가 있을 때 @ObjectType가 충돌하여 error가 발생한다. 그리고 InputType은 DB에 등록되는 것이 아니므로 isAbstract를 설정한다.
ref : https://docs.nestjs.com/graphql/mapped-types#partial
- @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());를 추가한다.
참고 자료
- 노마드 코더의 우버 이츠 클론 강의
- @Entity() : https://docs.nestjs.com/techniques/database#repository-pattern
- @ObjectType() : https://docs.nestjs.com/graphql/resolvers#object-types
- @InputType() : https://docs.nestjs.com/graphql/mapped-types#partial
'Project using Nest.js > E-commerce App' 카테고리의 다른 글
JWT with nestJS (0) 2021.09.02 login API on nestJS using graphql (0) 2021.09.02 Connect DB which is postgresql with nest.js (0) 2021.09.02 Graphql Configuration with nest.js (0) 2021.09.02 Config에 validation 설정하기 on nest.js with Joi (0) 2021.09.02 - @Entity() decorator는 entity를 정의할 수 있게 해준다. 그 안에 email, password 등의 필드들을 정의할 수 있다. TypeORM을 위한 코드다.