WEB/NestJS

[NestJS] 개요 및 REST API 예제 [1]

개요

NestJS Node.jsExpress/Fastify 기반으로 만들어졌다.

기본적으로 typescript를 지원한다.

 

다른 Node.js의 프레임워크에는 없는 구조를 가지고 있다.

따라서 기업 단위의 백엔드를 쉽게 만들 수 있다.

(사전 셋팅된 유용한 기능들이 많다. 대부분 자동으로 만들어 준다!!)

 

생성

nest new

//nest 설치 후 위 명령어를 입력하면 폴더 이름을 받고, 구조를 만들어 폴더가 생성된다.

생성 후 nest 명령어를 통해 필요한 것을 생성하고 import 해준다.

 

nest-cli

구조

간략한 구조

 

main.ts

여러 모듈을 하나의 모듈로 main.ts에서 생성하고 포트를 연다.

이때 pipe 설정과 같은 것을 이용해 데이터의 타당성을 검사할 수 있다.

이를 통해 서버를 보호할 수 있다.

 

import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe({
    whitelist: true,
    forbidNonWhitelisted: true,
    transform: true,
  }));
  await app.listen(3000);
}
bootstrap();

또한 transform을 이용해 받는 데이터의 타입(string)을 원하는 타입으로 변경할 수 있다!

 

module

모듈에서는 기본적으로 controllersproviders가 있다.

 

controllers :

express에서의 라우터 역할을 해준다. 

한 가지 큰 특징이 있는데, 원하는 것이 있다면 직접 요청해서 사용한다는 것이다.

@Controller('movies')
export class MoviesController {
    constructor(private readonly moivesService: MoviesService) { }

    @Get()
    getAll(): Movie[] {
        return this.moivesService.getAll();
    }

    @Get("search")
    search(@Query("year") searchingYear: string) {
        return `We are seraching for a movie made after: ${searchingYear}.`
    }

    @Get("/:id")
    getOne(@Param("id") movieId: number): Movie {
        return this.moivesService.getOne(movieId);
    }

    @Post()
    create(@Body() movieData: CreateMovieDto) {
        return this.moivesService.create(movieData);
    }

    @Delete("/:id")
    remove(@Param('id') moiveId: number) {
        return this.moivesService.deleteOne(moiveId);
    }

    @Patch('/:id')
    path(@Param('id') movieId: number, @Body() updateData: UpdateMovieDto) {
        return this.moivesService.update(movieId, updateData);
    }
}

 

providers : service;

function 역할을 한다.

import { Injectable, NotFoundException, ParseArrayPipe } from '@nestjs/common';
import { CreateMovieDto } from './dto/create-moive.dto';
import { UpdateMovieDto } from './dto/update-moive.dto';
import { Movie } from './entities/moive.entity';

@Injectable()
export class MoviesService {
    private moives: Movie[] = [];

    getAll(): Movie[] {
        return this.moives;
    }

    getOne(id: number): Movie {
        const movie = this.moives.find(movie => movie.id === id);
        if (!movie) {
            throw new NotFoundException(`Movie with ID : ${id} not found.`);
        }
        return movie;
    }

    deleteOne(id: number) {
        this.getOne(id);
        this.moives = this.moives.filter(movie => movie.id !== id);
    }

    create(movieData: CreateMovieDto) {
        this.moives.push({
            id: this.moives.length + 1,
            ...movieData,
        });
    }

    update(id: number, updateData: UpdateMovieDto) {
        const movie = this.getOne(id);
        this.deleteOne(id);
        this.moives.push({ ...movie, ...updateData });
    }
}

DTO를 이용해 가시성을 높일 수 있다.

 

추가적으로 import도 있다.

한가지 모듈에서는 한가지 기능을 하는 것이 원칙이므로, 다른 기능을 가져와 사용할 땐 import를 해주면 된다.

import { Module } from '@nestjs/common';
import { MoivesModule } from './moives/moives.module';
import { AppController } from './app.controller';

@Module({
  imports: [MoivesModule],
  controllers: [AppController],
  providers: [],
})
export class AppModule { }

 

-> main.ts에서는 하나의 모듈로 구동하기 때문에 app.module에서는 생성한 모듈들을 imports 해야 한다.