Nestjs를 배워보자 1일차 - Nestjs란?

2

Nestjs

목록 보기
1/9

Nestjs

Nodejs 진영의 서버 개발 라이브러리나 프레임워크에서 가장 많이 사용되고 있던 것은 express일 것이다. 그러나 express를 이용하여 서버를 개발해보신 분들은 알겠지만, express가 많은 걸 해준다기라기 보다는, 내가 원하는 모듈들을 레고 블럭마냥 갖다 붙인다라는 느낌이 들었을 것이다.

반면 Spring이나 Django 같은 프레임워크는 이미 프로젝트 구성이 완벽하게 되어있고, 내가 무언가 추가해나가면서 개발하기 보다는, 해당 프레임워크의 철학과 개발 방법을 배워나가는 느낌이 든다.

그리고, Nodejs 진영에도 이런 견고한 프레임워크가 몇 년전부터 아성을 부렸으니 그것이 Nestjs이다. 물론 1년 전 쯤에 Deno가 정식 출시되면서 Nest냐 Deno냐 경쟁이 있었지만, 둘 다 좋은 기술이기 때문에 그런건 상관하지말도록 하자

필자 역시도 몇 년 전부터 Nestjs를 듣고선 배워야지.. 배워야지... 생각했었는데, 생업(?)과 게으름에 밀려 이제야 공부하게 되었다.

https://www.youtube.com/watch?v=3JminDpCJNE

심지어 나의 이런 게으름을 아시는 건지 몇 달 만에 John Ahn 님께서 Nestjs 고퀄 무료 강의를 내주셨는데, 이걸 보고 공부를 안하는건 신성 모독이다.

인프런이나 유튜브, 각종 강의 사이트는 모두 돌아다니면서 K-강의들을 많이 들어봤지만 John Ahn님처럼 좋은 퀄리티와 실질적인 내용들을 다루는 강의는 거의 없다. (거기다 무료 강의까지... 심지어 유료 강의는 가격이 너무 싸신거 아닙니까..) 정말 존경합니다.

이제 각설하고 Nestjs에 대해서 알아보자

Nestjs는 Nodejs의 서버 프레임워크이다. express에 비해 더욱 탄탄한 기능들이 많이있기 때문에 많은 사랑을 받고 있다.

Nestjs란??

Nestjs란 효율적이고 확장 가능한 Nodejs 서버측 어플리케이션을 구축하기 위한 프레임워크이다. 프로그레시브 js를 사용하고 TS로 빌드되고 완벽하게 지원한다. 또한, OOP, FP, FRP(Functional Reactive Programming) 요소를 사용할 수 있게끔 할 수 있다.

Nestjs는 내부적으로 어떻게 구성되었는가??

내부적으로 Nest는 Express와 같은 강력한 HTTP 서버 프레임워크를 사용하며 선택적으로 Fastify를 사용하도록 구성할 수도 있다.

즉 Nest는 이러한 공통 Nodejs 프레임워크 (Express / Fastify) 위에 추상화 수준을 제공하지만, API를 개발자에게 직접 노출한다. 이를 통해 개발자는 기본 플랫폼에서 사용할 수 있는 수많은 타사 모듈을 자유롭게 활용할 수 있다.

Nestjs의 철학

Node 및 서버 측 JS를 위한 훌륭한 라이브러리, 도구들이 많이 존재하지만 이들 중 어느 것도 아키텍처의 주요 문제를 효과적으로 해결하지 못한다.

Nest는 개발자와 팀이 고도로 테스트 가능하고, 확장 가능하며 느슨하게 결합되고 유지 관리가 쉬운 어플리케이션을 만들 수 있는 즉시 사용 가능한 어플리케이션 아키텍처를 제공한다.

nestjs 설치

먼저 nodejs가 설치되었음을 가정한다.

nestjs를 설치하기 위해 먼저 cli을 설치해야 한다.

npm i -g @nestjs/cli
  • 해당 cli로 nestjs 프로젝트 생성하기
nest new 프로젝트이름

해당 명령어를 통해 쉽게 프로젝트를 구축할 수 있다.

만약 현재 폴더에서 프로젝트를 생성하고 싶다면 프로젝트 이름 부분에 ./ 울 넣어주면 된다.

  • 윈도우에서 설치 시 다음과 같은 에러가 발생할 경우
    필자의 경우에는 다음과 같은 에러가 발생했다.
nest : 이 시스템에서 스크립트를 실행할 수 없으므로...

이는 현재 계정에 권한이 없기 때문에 발생하는 에러이므로 다음과 같이 해결하면 된다.

  1. 윈도우 power shell을 시작 버튼에서 마우스 우클릭하여 관리자 버튼으로 실행

  2. Get-ExecutionPolicy 으로 현재 관리 상태 확인

  3. RemoteSigned 가 아니라면 Set-ExecutionPolicy RemoteSigned를 입력

이제 권한이 생겨서 프로젝트 생성이 가능하다.

프로젝트 구조

  1. eslintrc.js : 개발자들이 특정한 규칙을 가지고 코드를 깔끔하게 짤 수 있도록 도와주는 라이브러리, 타입스크립트를 쓰는 가이드 라인 제시, 문법에 오류가 나면 알려주는 역할 등등
  2. prettierrc.js : 주로 코드 형식을 맞추는데 활용, 작은 따옴표를 사용할 지 큰 따옴표를 사용할 지, indent 값을 2로 줄지 4로 줄지 등등 에로를 찾는 것이 아닌 코드 포맷터 역할을 한다.
  3. nest-cli.json : nest 프로젝트를 위해 특정한 설정을 할 수 있는 json 파일
  4. tsconfig.json : 어떻게 타입스크립트를 컴파일 할지 설정
  5. tsconfig.build.json : tsconfig.json의 연장선 파일이며 "excludes"에서는 빌드할 때 필요없는 파일들을 명시
  6. package.json : build는 운영환경을 위한 빌드, format은 린티에러가 났을 시 수정, start는 앱 시작
  7. src 폴더 : 대부분의 비즈니스 로직이 들어가는 곳
    1. main.ts는 앱을 생성하고 실행하는 곳,
    2. app.module.ts는 앱 모듈을 정의하는 곳

실행

설치 시 npm인지 yarn인지에 따라 명령어는 다르다.

src/main.ts 에 가면

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

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

다음과 같은 문법이 있을 것이다.
여기서 익숙한 부분인 listen() 메서드가 바로 포트를 여는 부분에 해당한다. 즉 3000번 포트를 열겠다는 것이다.

따라서 서버 실행 시 localhost:3000에 접근하면 된다.

npm start dev

http://localhost:3000/

접속하면 Hello World가 나온다.

어떻게 생긴 구조일까??

어디서 부터 Hello World가 나왔는 지를 확인해보자

먼저 main.ts 부분을 보도록 하자

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

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

굉장히 심플하다 NestFactory() 메서드에 인자로 AppModule을 넘겨주고 반환받은 app으로 실행을 한다.

그렇다면 AppModule이 있는 app.module 로 가보도록 하자

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

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

AppModule을 export하는데, @ 을 사용한다. 어노테이션 문법으로 어떤 모듈들이 import되고 controller로 쓰이고 providers로 사용되는 지 나타내고 있다.

spring이나 Django를 배워봤다면 느낌이 올 것이다. 아마 controllers는 url 요청이 왔을 때 처리하는 것이고, provider는 해당 url에 대한 로직이겠구나싶다.

먼저 AppController부분으로 가자

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get() 
  getHello(): string {
    return this.appService.getHello();
  }
}

역시나 익숙한 향기가 나는 class@Get() 어노테이션이다. 스프링과 굉장히 닮은 문법을 가지고 있다.

@Get()어노테이션은 default path인 /와 같은 기능을 한다. 따라서, 우리가 처음에 들어오는 화면에서 처리되는 서비스가 appService의 getHello() 메서드가 되는 것이다.

그러므로 app.service를 따라가보면,

import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}

다음이 나온다. Injectable()이 뭔지는 몰라도 return 값이 "Hello World" 인 것은 알겠다.

오늘은 큰 그림만 보도록 하자
큰 흐름은 다음과 같다.

url 요청 -> 컨트롤러가 url 라우팅 -> 해당 url에 맞는 Service 제공 -> url 응답

공식문서에 따르면 Nestjs는 내부적으로 Express 라이브러리를 사용하기 때문에 Express의 MVC 패턴을 적용할 수 있다고 한다.

https://docs.nestjs.com/techniques/mvc

더욱 더 스프링과 비슷하게 MVC 패턴을 js진영에서도 맛보고 즐길 수 있는 것이다.

오늘은 간단하게 구조만 살펴보고, 다음부터는 Nestjs의 특징과 구조에 대해 더 자세히 알아보도록 하자

0개의 댓글