«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Archives
Today
Total
관리 메뉴

올해는 머신러닝이다.

NestJS 필수로 알아야 하는 개념 정리 본문

스터디/NestJS

NestJS 필수로 알아야 하는 개념 정리

행복한 수지아빠 2025. 2. 13. 10:02

NestJS 개발을 위해 필수적으로 알아야 할 내용을 핵심 개념 중심으로 정리해 보겠습니다


1. NestJS 개요

NestJS는 TypeScript 기반의 Node.js 프레임워크로, Angular 스타일의 구조를 가져와 대규모 애플리케이션 개발에 최적화된 백엔드 프레임워크야. Express.js 또는 Fastify를 내부적으로 사용하고, **의존성 주입(DI)**과 데코레이터 기반 프로그래밍을 지원해.


2. 주요 개념

1) 모듈 (Modules)

모듈은 NestJS의 핵심 개념으로, 기능별로 코드를 분리하여 재사용성과 유지보수성을 높여줘.

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

@Module({
  imports: [],       // 다른 모듈을 가져옴
  controllers: [],   // 이 모듈의 컨트롤러 등록
  providers: [],     // 서비스(프로바이더) 등록
})
export class AppModule {}
  • @Module() 데코레이터를 사용해 모듈 정의
  • imports : 다른 모듈을 불러와서 연결
  • controllers : HTTP 요청을 처리하는 컨트롤러 등록
  • providers : 서비스, 리포지토리, 헬퍼 등을 주입

2) 컨트롤러 (Controllers)

컨트롤러는 HTTP 요청을 처리하는 역할을 해.

import { Controller, Get } from '@nestjs/common';

@Controller('users')
export class UserController {
  @Get()
  getUsers() {
    return [{ id: 1, name: 'John Doe' }];
  }
}
  • @Controller('users') → /users 경로에 매핑
  • @Get() → GET 요청을 처리

3) 서비스 (Services)

서비스는 비즈니스 로직을 담당하는 계층이야.

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

@Injectable()
export class UserService {
  getUsers() {
    return [{ id: 1, name: 'John Doe' }];
  }
}
  • @Injectable() → 의존성 주입을 가능하게 함

컨트롤러에서 서비스를 사용하려면 의존성 주입을 해야 해.

@Controller('users')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Get()
  getUsers() {
    return this.userService.getUsers();
  }
}

4) 의존성 주입 (Dependency Injection, DI)

NestJS의 핵심 기능 중 하나가 **의존성 주입(DI)**이야. NestJS에서는 @Injectable()을 이용해 서비스 간 의존성을 관리해.

@Injectable()
export class UserService {
  constructor(private readonly userRepository: UserRepository) {}
}
  • UserRepository가 UserService에 주입됨

5) 파이프 (Pipes)

데이터 검증과 변환을 담당하는 기능으로, DTO(Data Transfer Object)와 함께 사용됨.

import { IsString, IsInt } from 'class-validator';

export class CreateUserDto {
  @IsString()
  name: string;

  @IsInt()
  age: number;
}
  • class-validator와 class-transformer를 사용해 데이터 검증 가능

컨트롤러에서 DTO와 파이프 적용:

import { Body, Controller, Post, UsePipes, ValidationPipe } from '@nestjs/common';

@Controller('users')
export class UserController {
  @Post()
  @UsePipes(new ValidationPipe())  // 데이터 유효성 검사 적용
  createUser(@Body() createUserDto: CreateUserDto) {
    return createUserDto;
  }
}

6) 가드 (Guards)

가드는 인증 및 권한 부여를 담당하는 기능이야.

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    return request.headers.authorization === 'my-secret-token';
  }
}

컨트롤러에서 가드 적용:

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

@UseGuards(AuthGuard)
@Controller('users')
export class UserController {
  @Get()
  getUsers() {
    return [{ id: 1, name: 'John Doe' }];
  }
}

7) 인터셉터 (Interceptors)

인터셉터는 요청 및 응답을 가로채는 기능을 함. 주로 로깅, 응답 변환, 성능 측정 등에 사용돼.

import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before...');
    const now = Date.now();
    return next.handle().pipe(tap(() => console.log(`After... ${Date.now() - now}ms`)));
  }
}

컨트롤러에 적용:

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

@UseInterceptors(LoggingInterceptor)
@Controller('users')
export class UserController {
  @Get()
  getUsers() {
    return [{ id: 1, name: 'John Doe' }];
  }
}

8) 미들웨어 (Middleware)

NestJS의 미들웨어는 Express의 미들웨어와 유사하며, 요청을 가로채 특정 로직을 실행할 수 있어.

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

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    console.log(`Request... ${req.method} ${req.url}`);
    next();
  }
}

app.module.ts에서 미들웨어 적용:

import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';

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

3. 데이터베이스 연동 (TypeORM)

NestJS에서는 TypeORM을 사용하여 데이터베이스를 다룰 수 있어.

1) TypeORM 설정

import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',    // 데이터베이스 타입
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'password',
      database: 'test',
      autoLoadEntities: true,
      synchronize: true, // 개발 환경에서만 사용
    }),
  ],
})
export class AppModule {}

2) 엔티티 (Entity) 생성

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column()
  age: number;
}

3) Repository 사용

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';

@Injectable()
export class UserService {
  constructor(@InjectRepository(User) private userRepository: Repository<User>) {}

  async createUser(name: string, age: number) {
    const user = this.userRepository.create({ name, age });
    return this.userRepository.save(user);
  }
}

4. NestJS 필수 모듈

  • ConfigModule : 환경 변수 설정
  • JwtModule : JWT 인증
  • CacheModule : 캐싱 기능
  • ScheduleModule : 백그라운드 작업
  • GraphQLModule : GraphQL API 지원

이제 기본 개념과 구조를 알았으니, 실습하면서 익혀 보면 좋아.