2021. 6. 8. 14:21ㆍNest.js
평소에 Nest.js관련 글에 API 만들기 관련된 포스트가 없어 직접 만들면서 공부하게 되었습니다. 해당 블로그는 공부를 남기기 위한 용도입니다. 피드백 부탁드립니다.
1. Entity를 만들어보자.
유저와 관련된 Entity를 만들어 보도록 하겠습니다. 우선 src/entites
폴더를 생성 후 user.entity.ts
를 생성하겠습니다.
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class User {
@PrimaryGeneratedColumn("increment", { type: "bigint", unsigned: true, comment: "유저 유니크 아이디" })
userUid: number;
@Column()
userId: string;
@Column()
password: string;
}
서버를 시작하게 된다면 여러 로그중에 다음과 같은 로그를 볼 수 있습니다.
CREATE TABLE `user` (`userUid` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '유저 유니크 아이디', `userId` varchar(255) NOT NULL, `password` varchar(255) NOT NULL, PRIMARY KEY (`userUid`)) ENGINE=InnoDB
실제로 데이터베이스에 테이블이 생겼는지도 확인 해보겠습니다.
2. Database에 데이터를 삽입해보자.
Controller
와 Service
를 작성해서 테스트를 해보도록 하겠습니다. 우리가 만드는 것은 API 서버니까요.
LoginController
와 LoginService
를 만들도록 하겠습니다.
nest generate module login
nest generate controller login
nest generate service login
이와같이 전부 입력해도 되고 또는 줄여 쓸수도 있습니다.
nest g mo login
nest g --no-spec co login
nest g --no-spec s login
--no-spec
는 이름 그대로 .spec
테스트 파일을 생성하지 않는 것입니다.
또, 다르게 한번에 파일을 생성해주는 명령어도 존재합니다.
nest generate resource login
Nest.js
는 CLI로 생성할 시에 자동으로 모듈에 imports
providers
controllers
에 추가해줍니다. 참 편히하죠.
다음으로 LoginController
에서 EndPoint
를 생성해보겠습니다.
import { Controller, Get } from "@nestjs/common";
import { LoginService } from "./login.service";
@Controller("login")
export class LoginController {
constructor(private readonly loginService: LoginService) {}
@Get()
async test() {}
}
@Get()
으로 Get Method를 통해 받는 EndPoint라는 것을 선언합니다. 그 밑에 작성할 함수가 우리의 라우터 함수라고 할수 있겠습니다.
Controller
는 Service
와 소통창구라고 생각하시는 것도 좋을 것 같습니다. 우리의 비지니스 로직은 Service
에서 작성할 것입니다.
이제 LoginService
에 가서 나머지를 작성해보겠습니다.
import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { User } from "src/entities/user.entity";
import { Repository } from "typeorm";
@Injectable()
export class LoginService {
constructor(@InjectRepository(User) private readonly user: Repository<User>) {}
async test() {
return await this.user.save(
this.user.create({
userId: "TEST",
password: "TEST"
})
);
}
}
constructor
생성자를 통해 User
와 연결을 하고 test
함수에서는 하나의 user
인스턴스를 생성 후 Database에 저장하는 작업을 하고 있습니다.
여기서, 우리는 User
와 연결한다는 것을 알고 있지만 우리의 Nest.js
는 모르고 있습니다. 그래서 우리는 Nest.js
에게 알려줄 필요가 있습니다. LoginModule
로 가보겠습니다.
import { Module } from "@nestjs/common";
import { LoginService } from "./login.service";
import { LoginController } from "./login.controller";
import { TypeOrmModule } from "@nestjs/typeorm";
import { User } from "src/entities/user.entity";
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [LoginController],
providers: [LoginService]
})
export class LoginModule {}
이와같이, TypeOrmModule.forFeature
를 이용해 LoginModule
에서 User
를 Inject
할수 있도록 합니다.
이제, 다시 Controller
로 돌아가서 test
함수를 호출하겠습니다.
@Get()
async test() {
return this.loginService.test();
}
이제, 서버를 실행하고 API를 테스트해보도록 하겠습니다. API 테스트하는데 도움을 주는 포스트맨, 인섬니아 등의 툴이 존재하지만 우리는 이전 포스트에서 세팅했던 Swagger를 통해서 테스트를 해보도록 하겠습니다.
Try it out을 누르고 Execute를 눌러보세요. 다음과 같은 결과가 나왔나요?
실제 Database에서도 확인 해보겠습니다.
잘 생성이 되었습니다. 하지만 한가지 문제점이 존재합니다. 노출되어서는 안되는 password가 평문으로 저장이 되었습니다.
3. Hooks를 사용해보자.
평문으로 저장된 password를 암호화하기 위해서 우리는 ORM의 기능중 하나인 Hooks를 사용해보겠습니다. 기존 Database의 Trigger라고 생각하는게 이해하기 좋을것 같습니다.
우선, 암호화 라이브러리 bcrypt를 추가하겠습니다.
npm install --save bcrypt
그리고 User
로 돌아가 BeforeInsert
BeforeUpdate
를 작성 해보겠습니다. 이름 그대로 생성, 수정전에 실행이 되는 훅스입니다.
@BeforeInsert()
@BeforeUpdate()
async hashPassword(): Promise<void> {
if (this.password) {
try {
this.password = await bcrypt.hash(this.password, 10);
} catch (error) {
console.error(error);
throw new InternalServerErrorException();
}
}
}
insert
update
시에 password가 존재하면 기존 password에 암호화된 password를 대입하는 코드입니다.
이제 다시 스웨거로 돌아가 API를 실행해보겠습니다.
1번 데이터는 지우도록 하겠습니다.
다음 포스트에서는 실제 로그인기능을 구현해보도록 하겠습니다.
'Nest.js' 카테고리의 다른 글
[Nest.js] 맨땅에 헤딩 - Blog API 제작기 6편 (0) | 2021.06.30 |
---|---|
[Nest.js] 맨땅에 헤딩 - Blog API 제작기 5편 (0) | 2021.06.17 |
[Nest.js] 맨땅에 헤딩 - Blog API 제작기 3편 (0) | 2021.06.08 |
[Nest.js] 맨땅에 헤딩 - Blog API 제작기 2편 (0) | 2021.06.06 |
[Nest.js] 맨땅에 헤딩 - Blog API 제작기 1편 (0) | 2021.06.05 |