NestJS 03 | Account C.R.U.D #2

임종성·2021년 9월 4일
5

NestJS

목록 보기
3/13
post-thumbnail

지난 시간에 NestJs Project 설정 및 Database 연결, Entity & Repository를 작성했습니다. 이제 Service와 Controller를 작성하여 C.R.U.D를 구현해봅시다.

User Request DTO

DTO란 Data Transfer Obejct의 약자로 Data를 Object로 변환하는 객체입니다. 어떤한 값이 어떤 타입을 가지고, 필수인지 옵션인지 정의하기 위한 Class라고 생각할 수 있습니다.

Class Validator

NestJS는 class-validator 라이브러리를 사용하여 데코레이터 기반의 유효성 검사를 합니다. 이는 특히 처리된 속성의 metatype에 접근할 수 있어서 NestJS의 Pipe 기능과 결합할 때 매우 강력합니다.

User를 생성하기 위해서는user_name, user_account, user_password, user_email, user_type의 정보가 필요합니다. users.request.dto 파일을 생성하여 이 정보로 유효성 검사를 해봅시다.

@IsNotEmpty, @IsString와 같은 데코레이터가 바로 class validator입니다. 이는 Request로 받은 Data의 Type, 존재여부 등에 대한 유효성 검사를 실시합니다. 이제 모든 정보는 Not Empty여야 하고 반드시 String이어야 합니다.

User Service

Data를 처리하기 위한 Entity, Repository, DTO 작성을 모두 완료했으므로, 이제 Account C.R.U.D를 위한 Logic을 작성해봅시다.

Dependency Injection

C.R.U.D를 위해서는 Data에 대한 유효성 검사, 처리와 함께 Database에 접근하기 위해 Query를 사용하게 됩니다. 이러한 작업을 위해서 Service 내에서 Repository의 Dependency Injection(종속성 주입)이 필요합니다. 우리가 생성했던 UserRepositoryUsersService의 생성자에서 정의해줌으로 종속성을 주입해줄 수 있습니다.

단순히 UsersService에 종속성 주입한 것만으로는 사용할 수 없습니다. 실제로 UserRepository를 사용하기 위해서는 UserModule에서 import 해줘야 합니다. 추가로 UsersService가 외부에서 주입될 수 있도록 export도 해줍니다.

Create User

DI를 통해 UserRepository를 사용할 수 있으니, 이제 정말로 C.R.U.D를 해볼 차례입니다.

User를 생성하기 위해서 User의 정보인 DTO가 필요하므로 userCreateDto로 정보를 받습니다. Repository에 존재하는 기본 Method는 create, save, findOne, find, delete 등이 있습니다.

  • createuserCreateDto의 정보를 그대로 새로운 entity로 생성해줍니다.
  • save는 주어진 entity를 그대로 database에 저장해줍니다. 만약 entity가 DB에 존재한다면 Insert하고, 아니라면 update 해줍니다.

Get User

User의 정보를 읽기 위한 함수를 작성해줍니다. find method를 이용해 주어진 option에 부합하는 모든 entity를 list 형태로 불러오고, findOne을 통해 option에 맞는 첫번째 entity를 반환합니다. 만약 entity가 존재하지 않는다면 NotFoundException 에러를 반환해줍니다.

Update User

User의 id와 DTO를 모두 받고 존재 여부를 확인한 뒤, User가 존재한다면 UpdateDTO의 data를 존재하는 Entity에서 수정하고 save를 통해 DB에서 update해줍니다.

Delete User

User id를 이용해 delete method로 DB에서 삭제해줍니다.

User Controller

Account C.R.U.D를 하기위해 UsersService에서 DB와 연동하는 함수를 모두 작성했습니다. 이제 Controller에서 들어오는 Request에 대해 적절한 Response할 수 있도록 Routing Mechanism을 수행해줍시다.

Routing

UsersService에서 했던 Repository의 종속성 주입과 마찬가지로, Controller에서 UsersService의 종속성 주입을 위해 생성자를 작성해줍니다. Controller에서는 기본적으로 @Controller 데코레이터를 사용합니다. 이 데코레이터로 path 접두사를 사용함으로서 관련 Route 집합을 쉽게 Grouping하고 반복코드를 최소화 할 수 있습니다.

@Controller 데코레이터에서 경로 접두사 users를 지정하고 @Get HTTP Request Method 데코레이터를 사용하여 특정 Endpoint에 대한 핸들러를 생성하도록 지시합니다. 위와 같은 경우 /users/id와 같은 요청에 대한 Mapping을 해줍니다.

Request Object

우리는 Handler를 통해 Request의 세부정보에 접근해야합니다. 기본적으로 @Req 데코레이터를 사용하여 Access할 수 있습니다.

Request Object는 Request Query Parameter, Path Parameter, Header, Body 등 여러가지를 포함합니다. 굳이 @Req를 통해 정보를 가져올 필요는 없고, @Body, @Param, @Query와 같은 전용 데코레이터를 사용할 수 있습니다.

Pipe

Pipe는 입력된 Data를 원하는 방식으로 변환하거나 데이터를 평가하고 유효성 검사를 통해 확인 후 전달하기 위해 사용되는 Class입니다. 두 경우 모두 Controller의 Route Handler가 처리하는 Argument에서 작동합니다.

Request Object의 예시에서 @Param의 id에 적용되어 있는 ParseIntPipe를 확인해봅시다. Path Parameter로 사용되는 id는 반드시 Number Type이어야 하는데, /users/종성과 같이 string형태로 들어온다면 그저 Not Found 에러가 발생할 것입니다. 이러한 경우를 방지하기 위해 ParseIntPipe()를 사용해서 요청된 id가 int가 아니라면 Int Type Data를 넣어주십시오와 같은 예외를 반환합니다.

Status Code

Response Status Code는 기본적으로 200입니다. Handler에 @HttpCode() 데코레이터를 추가하여 Status를 변경할 수 있습니다.

Delete Method의 경우 Status Code는 No Content라는 의미의 204 입니다. @HttpCode(204) 데코레이터를 사용하여 Status Code를 변경해주었습니다.

Account C.R.U.D

이제 PostMan을 이용해 API가 제대로 구현되었는지 확인해봅시다!

npm run prebuild 후에 npm run start:dev를 실행하여 오류없이 작동하는지 확인합니다.

제대로 실행되는 것을 확인하고, CRUD를 해봅시다.

Create User

Get User


Update User(id=1)

Delete User(id=1)

Database

제대로 CRUD 기능이 구현된 것을 확인할 수 있었습니다!


TIL

Account CRUD 구현을 한번 더 진행하면서 내용을 정리하고 핵심 개념에 대해 더 이해할 수 있던 시간이었습니다. 생소한 개념을 접하면서 두루뭉실하게 이해하고 넘어갔었는데, 기술블로그를 정리하면서 진행하니 확실하게 개념이 정리되는 것 같습니다.

실제로 실습하는 과정에서 아주 기본적인 기능만 넣었기 때문에 더 공부해야할 것들이 많습니다. 회원가입에서의 아이디, 이메일, 비밀번호의 유효성 검사와 비밀번호의 암호화, 로그인에서의 JWT와 Passport, Guard를 이용한 인증, 인가가 필요합니다. 또한 여러개의 Entity를 사용하는 경우의 TypeOrm을 활용한 Relationship 정의와 QueryBuilder, Repostiroy Method 생성 등.. 2차 프로젝트 수준으로 API를 구현하기 위해 해야할 것들이 아직 많습니다.

이제 어느정도 공부를 한만큼, 앞으로는 더 빠르게 개념을 습득할 것 같습니다. 최대한 노력해서 NestJS의 모든 기능을 써보도록 하겠습니다.

profile
어디를 가든 마음을 다해 가자

4개의 댓글

comment-user-thumbnail
2021년 9월 7일

언더바를 넣어요?

1개의 답글