ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Nestjs Request Lifecycle
    Node 2024. 11. 24. 18:41

    Nestjs Request Lifecycle

    1. Middleware (미들웨어)

    • 위치: 요청 처리의 가장 첫 단계
    • 역할: HTTP 요청/응답을 가로채어 수정하거나 처리 여부를 결정
    • 주요 기능:
      • 요청 로깅
      • 헤더 조작
      • 요청 본문 파싱
      • CORS 설정
    // Interceptor 구현
    @Injectable()
    export class LoggerMiddleware implements NestMiddleware {
      use(req: Request, res: Response, next: NextFunction) {
        console.log(`Request ${req.method} ${req.url}`);
        next();
      }
    }
    
    // Interceptor 적용
    import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
    import { LoggerMiddleware } from './common/middleware/logger.middleware';
    import { CatsModule } from './cats/cats.module';
    
    @Module({
      imports: [CatsModule],
    })
    export class AppModule implements NestModule {
      configure(consumer: MiddlewareConsumer) {
        consumer
          .apply(LoggerMiddleware)
          .forRoutes('cats');
      }
    }

    2. Guards(가드)

    • 위치: 미들웨어 다음, 라우트 핸들러 이전
    • 역할: 인증/인가 등 요청의 실행 허가 여부를 결정
    • 주요 기능:
      • 인증 상태 확인
      • 권한 체크
      • 접근 제어
      • IP 기반 필터링
    @Injectable()
    export class AuthGuard implements CanActivate {
      canActivate(context: ExecutionContext): boolean {
        const request = context.switchToHttp().getRequest();
        return !!request.headers.authorization;
      }
    }

    3. Interceptors (인터셉터)

    • 위치: 가드 다음, 라우트 핸들러 전후
    • 역할: 요청/응답 변환, 추가 로직 실행
    • 주요 기능:
      • 응답 데이터 변환
      • 성능 모니터링
      • 캐시 처리
      • 로깅
    @Injectable()
    export class TimingInterceptor implements NestInterceptor {
      intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
        const start = Date.now();
        return next.handle().pipe(
          tap(() => console.log(`Request took ${Date.now() - start}ms`))
        );
      }
    }

    4. Pipes (파이프)

    • 위치: 인터셉터와 라우트 핸들러 사이
    • 역할: 데이터 변환 및 유효성 검사
    • 주요 기능:
      • 입력 데이터 유효성 검사
      • 데이터 타입 변환
      • DTO 검증
      • 기본값 설정
    @Post()
    createUser(@Body(new ValidationPipe()) createUserDto: CreateUserDto) {
      return this.usersService.create(createUserDto);
    }

    5. Controller (컨트롤러)

    • 위치: 파이프 다음, 비즈니스 로직 이전
    • 역할: 요청 라우팅 및 요청/응답 처리
    • 주요 기능:
      • 요청 경로 매핑
      • 요청 파라미터 추출
      • 서비스 계층 호출
    @Controller('users')
    export class UsersController {
      @Get(':id')
      findOne(@Param('id') id: string) {
        return this.usersService.findOne(id);
      }
    }

    6. Service (서비스)

    • 위치: 컨트롤러 다음
    • 역할: 비즈니스 로직 실행
    • 주요 기능:
      • 데이터 처리
      • 외부 서비스 통신
      • 데이터베이스 작업
    @Injectable()
    export class UsersService {
      async findOne(id: string): Promise<User> {
        return this.usersRepository.findOne(id);
      }
    }

    7. Exception Filters (예외 필터)

    • 위치: 전체 요청/응답 사이클에서 예외 발생 시
    • 역할: 예외 처리 및 에러 응답 생성
    • 주요 기능:
      • 에러 로깅
      • 사용자 정의 에러 응답
      • 예외 변환
    @Catch(HttpException)
    export class HttpExceptionFilter implements ExceptionFilter {
      catch(exception: HttpException, host: ArgumentsHost) {
        const ctx = host.switchToHttp();
        const response = ctx.getResponse();
        const status = exception.getStatus();
    
        response.status(status).json({
          statusCode: status,
          timestamp: new Date().toISOString(),
          message: exception.message,
        });
      }
    }

     

    통합 사용 예시

    @UseGuards(AuthGuard)
    @UseInterceptors(LoggingInterceptor)
    @UseFilters(HttpExceptionFilter)
    @Controller('users')
    export class UsersController {
      @Post()
      @UsePipes(ValidationPipe)
      create(@Body() createUserDto: CreateUserDto) {
        return this.usersService.create(createUserDto);
      }
    }
Designed by Tistory.