Nest.js - DTO 및 Middleware

0

Nest Logo

📚 NestJS 실전 프로젝트 가이드


1. DTO 구현과 Validation 적용, 데코레이터 사용

DTO(데이터 전송 객체)란?

  • 데이터의 유효성 검증과 API 문서화를 위해 사용합니다.
  • class-validator@nestjs/swagger의 데코레이터를 함께 사용합니다.
  • 클라이언트와 서버 간에 데이터를 주고받을 때 사용하는 "형식(틀)"

"이 API를 호출할 때, 이런 데이터 구조로 보내주세요!"
또는
"서버는 이런 데이터 구조로 응답해줄게요!"

라고 약속된 데이터의 형태를 정의하는 거예요.

예시: CreateBoardDto

import { ApiProperty } from '@nestjs/swagger';
import { MaxLength, MinLength, IsNotEmpty } from 'class-validator';

export class CreateBoardDto {
  @MinLength(2)
  @MaxLength(20)
  @IsNotEmpty()
  @ApiProperty({
    description: '이름',
    required: true,
    example: '홍길동',
  })
  name: string;

  @IsNotEmpty()
  @ApiProperty({
    description: '내용',
    required: true,
    example: '내용입니다.',
  })
  content: string;
}

예시: UpdateBoardDto (부분 수정 가능)

import { IsOptional, MaxLength, MinLength } from 'class-validator';

export class UpdateBoardDto {
  @MinLength(2)
  @MaxLength(20)
  @IsOptional()
  name?: string;

  @IsOptional()
  contents?: string;
}

2. Exception Filter 설정 및 글로벌 적용

Exception Filter란?

  • NestJS에서 예외 발생 시 공통적으로 처리할 로직을 정의할 수 있습니다.

예시: HttpExceptionFilter

import {
  ExceptionFilter,
  ArgumentsHost,
  HttpException,
  Catch,
} from '@nestjs/common';
import { Request, Response } from 'express';

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const status = exception.getStatus();

    response.status(status).json({
      statusCode: status,
      timestamp: new Date().toISOString(),
      path: ctx.getRequest<Request>().url,
    });
  }
}

글로벌 필터로 등록하기

main.ts에서 아래와 같이 등록합니다.

import { HttpExceptionFilter } from './exceptions/http.exceptions';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  // ...생략
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

3. Middleware 설정 방법

Middleware란?

  • 요청(Request)과 응답(Response) 사이에서 실행되는 함수로, 로깅, 인증 등 다양한 용도로 사용됩니다.

예시: LoggingMiddleware

import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
import { NextFunction, Request, Response } from 'express';

@Injectable()
export class LoggingMiddleware implements NestMiddleware {
  private readonly logger = new Logger();
  use(req: Request, res: Response, next: NextFunction) {
    const { method, originalUrl } = req;
    const startTime = Date.now();

    res.on('finish', () => {
      const { statusCode } = res;
      const responseTime = Date.now() - startTime;
      this.logger.log(
        `[${method}] ${originalUrl}: ${statusCode} ${responseTime}ms`,
      );
    });
    next();
  }
}

AppModule에 적용하기

import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { LoggingMiddleware } from './middleware/logging.middleware';

@Module({
  // ...생략
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoggingMiddleware).forRoutes('*');
  }
}

4. ConfigModule 사용법

1) 패키지 설치

npm install @nestjs/config

2) 환경설정 파일 작성

src/config/configuration.ts

export default () => ({
  ENVIRONMENT: process.env.ENVIRONMENT,
});

src/config/index.ts

import { ConfigModule } from '@nestjs/config';
import configuration from './configuration';

export default ({} = {}) =>
  ConfigModule.forRoot({
    isGlobal: true,
    envFilePath: `.env.local`,
    load: [configuration],
  });

3) AppModule에 적용

import ConfigModule from './config';

@Module({
  imports: [ConfigModule() /* ...다른 모듈 */],
  // ...
})
export class AppModule implements NestModule {
  // ...
}

5. 주요 패키지 설치 목록

npm install class-validator class-transformer @nestjs/config @nestjs/swagger

6. 참고

  • DTO, Validation, Exception Filter, Middleware, ConfigModule 등은 NestJS 공식문서에서 더 자세히 확인할 수 있습니다.
  • 환경변수 파일(.env.local 등)은 프로젝트 루트에 위치시켜 사용합니다.

profile
하루하루 기록하기!

0개의 댓글