[Nest.js] Nest.js 란 무엇일까? - 개요와 프로젝트 생성

정지현·2022년 10월 23일
2

요즘 만들고 있는 토이프로젝트인 전역일 계산기와 회사 위키에 사용할 서버로 Nest.js 를 도입해보려고 한다.

이전에도 사용해본 경험은 있지만, 보다 디테일하게 알고 기록해두면 좋을 것 같아서 포스팅을 해본다!

🔨 Nest.js 란?

Nest.js 는 Node.js 를 기반으로 한 서버 어플리케이션을 개발하기 위한 프레임워크이다.

내부적으로 Express 프레임워크(기본 설정)와 Fastify 프레임워크를 선택해서 사용할 수 있다고 한다.

또한, Nest.js 는 상기 프레임워크의 API 를 직접적으로 사용할 수 있도록 제공한다. Express 혹은 Fastify 에 더욱 더 익숙한 개발자라면 서버 어플리케이션 개발에 있어서 보다 큰 자유도를 가질 수 있을 듯하다.

무엇보다 기존 Express 와는 달리 정형화된 아키텍처를 지니고 있다는 점에 차이가 있으며, 실제 사용해보니 스프링과 비슷한 구조였다는 점에 주목하면 좋을 듯하다.

Controller, Service 등의 개념이 이와 유사하며, 다양한 Decorator(스프링의 Annotation 과 같은 역할)가 사용된다는 점에서 기존 스프링 프레임워크를 다룬 개발자라면 사용해볼만할 것 같다.

또한, Jest 라고 하는 테스트 환경이 자동으로 제공되며, Nest.js 에서 제공하는 CLI 를 통해 파일을 생성하면 테스트를 위한 spec 파일이 자동으로 생성된다고 한다!

📖 Nest.js 의 철학

공식 도큐먼트에 따르면, 최근 몇 년 동안 Node.js 와 자바스크립트는 프론트엔드와 백엔드의 공용어가 되었다고 한다.

즉, 백엔드와 프론트엔드가 자바스크립트(또는 타입스크립트)를 통해 동일한 언어로 개발될 수 있는 환경이 되었다는 것이다!

그런데 여기서 Nest.js 는 React, Vue, Angular 의 경우 개발자의 생산성과 테스트 등을 보다 수월하게 해주기 위한 아키텍처가 존재하나, 자바스크립트 계열의 백엔드 프레임워크에서는 이를 보장하기 위한 아키텍처가 전무했다는 점에 주목한 듯 하다.

정말로, Express 프레임워크의 경우 프로젝트의 아키텍처는 보일러 플레이트가 아닌 이상 개발자의 경험, 재량에 따라 결정되는 경우가 많다. 이는 Nest.js 와 Express 를 비교한 글 에서 확인할 수 있다.

Express.js is a framework without strong opinions — in other words, un-opinionated. This means it doesn’t have a set of pre-defined rules to follow. Developers often use this opportunity to experiment with different scenarios and write code as needed.

Express does not require a specific structure, which can provide flexibility for small or one-person development teams. However, this can become a problem as team size or app complexity grows, especially with developers working on different aspects of the app.

이에 따라 각각의 개발자들과 개발팀이 서버 어플리케이션 개발에 있어서 테스트가 용이하며, 확장성 있고, 낮은 결합도와 높은 유지보수성을 지닌 형태의 프레임워크인 Nest.js 를 만들었다고 한다. (쓰다보니 논문 1장 쓰는 것과 비슷한 느낌이든다...?)

👏 Express VS Nest.js 의 인지도

Node.js 프레임워크 인지도 Github 에 따르면, 2022년 10월 08일 기준 Express 는 약 58,000 건의 Stars 를 기록하고 있으며, NestJS 는 2022년 10월 21일 기준 약 51,000건의 Stars를 기록하고 있다.

Nest.js 는 내부적으로 Express 를 기본 프레임워크로 사용하는데, Express 와 Stars 의 개수가 나름 근사치(?) 라는 점에서는 분명 유의한 이유가 있을 것이다.

그만큼 Nest.js 는 사람들에게도 널리 잘 알려진 프레임워크라는 것이다!

❓ 그래서 어떻게 쓰는건데?

Nest.js 는 개발의 편의성을 증대시켜주기 위한 Nest CLI 를 함께 제공한다!

$ npm i -g @nestjs/cli # Nest.js CLI 전역 설치
$ nest new project-name # Nest.js 프로젝트 생성

상기 명령어를 실행시키면, Nest.js 의 기본 프로젝트 구조를 지닌 어플리케이션이 생성된다.

공식 도큐먼트에 따르면, 타입스크립트의 Strict 모드를 설정한 상태로 생성하고 싶다면 --strict 플래그를 추가하면 된다고 한다.

직접 생성해보았는데, 다음과 같은 프로젝트 구조가 완성된다.

여기에서 주목해야할 것은, src 폴더 내의 파일들이다. 각각의 파일들에 대한 설명은 다음과 같다.

  • app.controller.ts: GET 메소드를 한 개만 갖고 있는 기본 컨트롤러, getHello 라는 메소드가 포함되어 있다.
  • app.controller.spec.ts: app.controller.ts 컨트롤러에 대한 유닛 테스트를 위한 파일이다.
  • app.module.ts: 전체 어플리케이션의 루트 모듈이다. (아직까지는 모듈의 개념이 무엇인지는 공식 도큐먼트를 좀 더 읽어봐야할 것 같다.)
  • app.service.ts: 비즈니스 로직을 담는 기본 서비스이다. app.controller.ts 의 getHello 메소드를 처리하기 위한 비즈니스 로직이 예제로 작성되어있다.
  • main.ts: Nest.js 어플리케이션 인스턴스를 생성하기 위한 NestFactory 를 사용하는 엔트리 파일이라고 한다. 스프링 부트의 SpringBootAppliation.java 와 동일한 포지션인 것 같다.

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();

Nest.js 서버 어플리케이션을 만들기 위해서는 코어 클래스인 NestFactory 를 사용한다고 한다.

create() 메소드는 어플리케이션 객체를 반환하며, INestApplication 인터페이스의 형태를 띤다고 한다.

도큐먼트에서는 create() 메소드의 제네릭으로 NestExpressApplication 또는 NestFastifyApplication 를 작성하면 app 객체가 각각의 프레임워크의 메소드만을 갖게 된다는데.. Fastify 를 사용하고 싶을 경우 여기를 참고하도록 하자.

이제 실행시켜보자! package.json 를 확인해본다.

  "scripts": {
    "prebuild": "rimraf dist",
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch",
    "start:prod": "node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  }

엄청 많은데, npm run start 를 통해 실행시키면 3000번 포트로 서버가 열린다.

npm run start:dev 를 입력하면, 변경사항이 감지되었을 경우 직접 서버를 다시 키지 않아도 이를 감지하여 서버를 자동으로 재시동해준다.

후기

개발자가 되기 전에는 막연히 백엔드 개발자가 되고 싶어서 Express 를 공부해보기 시작했다. 그런데 그 당시에 가장 당황했던게, Express 서버 어플리케이션을 구축하는데 너무 비어있는 도화지 같다는 생각이 들었다.

대학에서 스프링을 배울 때에는 기본 프로젝트 아키텍처가 있었던 것 같은데, 아무 것도 없는 상태에서 스스로 프로젝트를 구성해나가는 것이 그때 당시에는 나에게 있어서 매우 두려운 일 같았다. 물론 그 결과 스프링을 열심히 배워서 이걸로 밥벌이하고 있긴 하지만..

계속 스프링 부트를 사용하다가 무슨 바람이 불어서인지는 몰라도 Nest.js 를 사용해보고 싶다는 마음이 생겼다. 스타트업에서도 생각보다 많이 도입하는 것으로 보이기도 하고, 무엇보다 토이 프로젝트를 React 로 진행하는데, 백엔드와 프론트엔드의 언어 스택을 함께 맞춰보면 어떨까? 하는 생각이 문득 들었다.

마음 같아서는 스프링 부트와 Nest.js 를 동시에 자유롭게 활용할 수 있는 개발자가 되고 싶지만, 그러려면 얼마나 많은 노력이 필요할지는 모르겠다. 열심히 배우고, 열심히 기록해야겠다.

profile
나를 성장시키는 좌절에 감사하고 즐기려고 노력 중

0개의 댓글