NestJS로 API 만들기 - 1
Introduction
NestJS는 백엔드를 구성할 수 있게 한다.
node.js 위에서 움직이는 프레임워크다.
Typescript에 기반하고 있다.
yarn보다 npm이 더 안정성 있으므로 package는 npm을 사용한다.
$ npm i -g @nestjs/cli
$ nest new project-name
백엔드 API를 구성하기 위해 Insomnia Core를 다운로드 해야 한다.
Architecture of NestJS
main에서 모듈로 이동하고, 모듈에서 컨트롤러로 이동하고, 서비스로 이동하면 텍스트를 나타내는 부분을 알 수 있다.
서비스는 클래스며 함수를 가지고 있다.
모듈은 어플리케이션의 일부로, 기능을 담당할 수 있다.
인증을 담당하는 어플리케이션이 있다면 유저 모듈이 되는 것이다.
@로 나타내는 부분은 데코레이터다.
데코레이터는 클래스에 함수 기능을 추가할 수 있다.
클래스 위의 함수이며 클래스를 위해 움직인다.
꾸며주는 함수나 클래스와 붙어있어야 한다. space를 주지 않도록 주의한다.
컨트롤러는 라우터 같은 존재다.
해당하는 url 값일 때 함수를 실행한다.
따라서 라우터는 따로 만들지 않아도 된다.
NextJS는 컨트롤러를 비즈니스 로직과 구분하고 싶어한다.
따라서 컨트롤러는 url을 가져오는 역할과 함수를 실행하는 역할을 담당하고(return function), 나머지 로직은 서비스로 이동한다.
REST API
1. 컨트롤러 생성
nest를 터미널에 입력하면 cli로 사용할 수 있는 명령어가 나타난다.
generate로 nest element를 생성할 수 있음을 알 수 있다.
nest g co
컨트롤러 이름을 입력한다.
컨트롤러가 생성되며 app.module.ts 폴더의 controllers에 이미 입력되어 있음을 알 수 있다.
@Cntroller('movies')로 컨트롤러가 작성되었다면 /movies 라우터로 작동될 것이다.
2. 요청하려는 데이터를 명시한다

param으로 요청하는 것을 잊으면 데이터가 불러와지지 않는다.

3. 생성하고 싶은 데이터가 있는 경우(create) Body로 넘겨주고 싶다면 명시해서 넘겨준다.
Patch도 같은 조건으로 넘겨줘야 한다.

4. 데이터를 검색을 쿼리로 구현하고 싶을 때 Get('search')으로 구현할 수 있다.
다만 Get(':id') 아래에 있다면 search도 id중 하나로 판단한다.
위치에 주의해야 한다.

5. 서비스 파일을 만든다.
npm g s
서비스가 생성되며 app.module.ts 폴더의 providers에 이미 입력되어 있음을 알 수 있다.
6. 파일을 생성하여 타입을 지정한다.
타입은 export class로 지정한다.

7. 컨트롤러에서 서비스를 constructor로 요청하여 파일 내에서 this로 접근이 가능하게 한다.
서비스에 함수의 내용을 넣는다.


8. 원하는 데이터가 없을 때 오류 처리를 한다.
NestJS에서 제공하는 NotFoundException 기능을 활용하면 편리하다.
delete에서 getOne을 호출하므로 id가 없다면 throw new NotFoundException이 발동된다.
값이 있다면 movie에 저장된다.

9. 원하는 데이터 형식이 아니면 데이터를 create 할 수 없게 한다.
데이터 전송 객체(Data Transfer Object)를 class로 작성한다.
그러나 DTO만으로는 데이터 유효성을 검증할 수 없다.
main.ts에 pipe를 생성해야 한다.
class의 유효성을 검사하기 위해 라이브러리를 설치한다.
npm i class-transformer
npm i class-validator
main.ts에 pipe를 생성해야 한다.
Whitelist와 forbidNonWhitelisted 모두 유효성 검사를 엄격하게 할 수 있는 옵션이다.
transform은 데이터의 형식을 바꾸어준다.

DTO에 검사할 타입을 입력한다.

컨트롤러와 서비스에 해당 데이터 형식을 적용한다.


10. 업데이트를 위한 타입을 지정한다.
타입을 변환시켜 사용할 수 있게 하는 라이브러리를 설치한다.
npm i @nestjs/mapped-types
PartialType extends하여 타입을 확장시킨다.
모든 항목을 optional한 표시를 ?으로 하는 것보다 더 알기 쉬운 코드가 된다.

각각의 원소에 대해 타입 검사를 하던 것을 optional하게 바꾸어 작동하게 한다.
이 항목을 넣지 않으면 extends로 모두 optional하게 해도 each:true에서 오류가 발생한다.

11. 파일 구조를 다시 개편한다.
app modules에는 app service와 app controller만 있어야 하므로 module을 생성하여 파일 구조를 변경한다.
module의 provider에 들어간 서비스 파일의 데이터를 읽어와 컨트롤러 안에 넣어준다.
12. Express 앱에 접근할 수 있다.
Req, Res를 이용하여 접근할 수 있다. 그러나 많이 사용하는 것은 좋지 않다.
NestJS는 두개의 프레임워크로 돌아가기 때문에 다른 하나(Festify)를 사용할 때 문제가 생길 수 있다.