본 내용은 내일배움캠프에서 활동한 내용을 기록한 글입니다.
장점 :
단점 :
Express에 레이어드 아키텍처 패턴을 적용하려면 프레임워크의 구조를 스스로 설계해서 구현해야 함
이는 요구사항 변경 및 기획이 추가됨에 따라 필요한 개념들을 새롭게 추가해야 함
Nest.js는 TypeScript 기반의 웹 프레임워크이기 때문에 타입을 체크해서 여러 예외 상황을 사전에 방지할 수 있음
그리고 명령어 하나로 쉽고 간편하게 계층 생성이 가능함
nest g co posts
: nest로 posts라는 컨트롤러를 만들겠다 란 뜻의 명령어
컨트롤러 뿐만 아니라 서비스, 미들웨어, 인터셉터 등 웹서버에 필요한 다양한 구성요소를 커맨드로 정확하게 구현 가능함
이는 개발자에게 보다 더 로직에 집중할 수 있는 환경을 제공하는 것임
npm i -g @nestjs/cli
nest
nest new sparta-nest
? Which package manager would you ❤️ to use? (Use arrow keys)
❯ npm
yarn
pnpm
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
main.ts 파일은 Nest.js 웹 어플리케이션의 진입점으로, 즉 서버 실행시 처음 동작하는 구간임
const app = await NestFactory.create(AppModule);
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
모듈은 기능별로 src 디렉토리 밑에 생성하면 됨 ex) user.module.ts, post.module.ts 등
@
가 붙은 키워드를 데코레이터라고 함
데코레이터는 해당 클래스나 함수가 어떤 역할을 하는 지 Nest.js에게 알려주는 역할을 함
모듈에는 imports, controllers, prociders, exports 속성이 존재함
여러 모듈에서 공통으로 사용할 때 좋음
특정 모듈 내에서만 사용되고 다른 모듈에서는 사용되지 않을 때 좋음
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();
}
}
constructor(private readonly appService: AppService) {}
위의 코드를 해석하면 인자로 AppService 객체를 받아서 this.appService라는 멤버 변수에 AppService 객체가 주입된다는 것을 의미
이러한 것을 생성자를 통한 의존성 주입(DI)이라고 함
그리고 컨트롤러는 서비스를 반드시 의존해야 함
컨트롤러의 데코레이터는 Http Method를 의미함
@Post
, @Put
, @Patch
, @Delete
, @Post
데코레이터가 이미 준비되어 있음
import { Injectable } from '@nestjs/common';
@Injectable() // <- 난 Inject(주입)될 수 있어! 라고 선언하는 것이에요.
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
서비스 객체는 실제로 레포지토리를 의존하며 비즈니스 로직 수행을 담당함
서비스 역시 레포지토리를 반드시 의존해야 하며 이는 생성자를 통한 의존성 주입(DI)로 해결해야 함
서비스에서 사용한 @Injectable
데코레이터는 다른 모듈에서 AppService를 의존성 주입을 위해 가져다 사용해도 된다고 표시한 것임
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
// 1. 사용하고 싶은 서비스 타입 객체를 미리 선언합니다.
private appService: AppService
constructor() {
// 2. 생성자에서 실제로 사용할 서비스 객체를 직접 생성합니다.
this.appService = new AppService();
}
...
}
위와 같은 전통적인 방식은 AppController가 AppService와 강하게 결하뵈더 있음
즉, AppService가 변경되면 개발자도 그에 맞춰 코드를 수정해야하는 번거로움이 발생함
그래서 IoC는 객체의 생명주기 관리 자체를 외부에 위임해서 관리함
IoC 원칙은 모듈 간 결합도를 낮추기 때문에 하나의 모듈이 변경되어도 다른 모듈들에는 영향을 최소화 시킴
constructor(private readonly appService: AppService) {}
그래서 위와 같이 사용하면 AppService의 인스턴스는 Nest.js의 DI 컨테이너에 의해 생성되고 관리됨
즉, 개발자는 직접 객체를 생성하거나 관리할 필요없이 코드의 결합도를 낮추고, 유연성과 테스트 용이성을 향상시킴
일단 오늘 3주차 강의를 진행할 예정
만약 3주차를 다 듣는다면 내일 Nest.js 강의를 끝낼 예정
TypeScript + Nest.js + TypeORM 형태로 과제가 발제될 예정
미리 올라온 발제 문제를 보니 이번에는 기존 과제를 재활용하지 않고 새로운 주제로 진행함
생각보다 구현할게 많아 보여서 재밌어 보임
오늘은 Nest.js 강의 1주차, 2주차를 시청함
1주차는 간단한 소개 뿐이었지만 2주차에는 Nest.js의 기본적인 구조에 대한 설명이었음
2주차의 내용은 생각보다 어려워서 정리하고 이해하는 데 시간이 오래 걸렸음
3주차 강의는 다 할 수 있을지 모르겠지만 최대한 진행할 예정
␍
eslint (prettier/prettier) 에러빨간줄로 에러 표시가 되어있지만 실제로 동작에는 아무런 문제가 없음
하지만 계속 에러 표시로 남기기에는 너무 거슬리기 때문에 문제 해결을 위해 방법을 찾아봄
원인은 ESLint에서의 줄바꿈에 대한 에러를 표시한 것임 (LF, CRLF 문제)
그래서 .eslintrc.js 에서 설정을 바꿔주기로 함
우선 아래와 같이 .eslintrc.js 파일로 이동
'prettier/prettier': [
'error',
{
endOfLine: 'auto',
},
],
Nest.js 강의를 시청하다보니 문득 이런 생각이 들었음
'이렇게 여러면에서 좋은 Nest.js가 나왔는데 왜 아직도 Express를 많이 사용하는 걸까?'
생각보다 여러가지 이유가 있었지만 그렇게 큰 이유는 아닌 것 같음
저도 계속 esLint 밑줄이 신경쓰였는데 적어주신 코드를 적으니 깔끔하게 해결되었네요 감사합니다(__)