TIL - 20260219

juni·2026년 2월 19일

TIL

목록 보기
272/316

0219 NestJS 기초 (2/N): 모듈, CRUD, 데이터베이스 연동(TypeORM)


✅ 1. NestJS CLI를 이용한 코드 생성 (Scaffolding)

  • NestJS CLI는 반복적인 모듈, 컨트롤러, 서비스 파일 생성을 자동화하여 개발 생산성을 크게 향상시킵니다.

  • 리소스(Resource) 한번에 생성하기:

    nest generate resource movies
    # 또는 축약형
    nest g res movies
    • 위 명령어를 실행하면, movies라는 기능에 필요한 파일들이 자동으로 생성되고, 루트 모듈(app.module.ts)에 등록까지 완료됩니다.
      • movies.module.ts (모듈)
      • movies.controller.ts (컨트롤러)
      • movies.service.ts (서비스)
      • dto/create-movie.dto.ts (데이터 전송 객체)
      • entities/movie.entity.ts (데이터베이스 엔티티)

✅ 2. CRUD API의 기본 흐름

  • 데이터를 생성(Create), 조회(Read), 수정(Update), 삭제(Delete)하는 기본적인 API는 Controller → Service의 흐름으로 동작합니다.

➕ 2-1. 컨트롤러 (Controller)

  • 역할: URL 경로(Path)와 HTTP 메서드(Method)를 정의하고, 요청 본문(Body)이나 파라미터(Param)를 받아 서비스에 전달합니다.
  • 주요 데코레이터:
    • @Controller('movies'): 이 컨트롤러의 기본 경로를 /movies로 설정.
    • @Get(): GET /movies
    • @Get(':id'): GET /movies/1
    • @Post(): POST /movies
    • @Patch(':id'): PATCH /movies/1
    • @Delete(':id'): DELETE /movies/1
    • @Param('id'): URL 경로의 파라미터(:id)를 가져옴.
    • @Body(): 요청의 본문(JSON 데이터)을 가져옴.

➕ 2-2. 서비스 (Service)

  • 역할: 컨트롤러로부터 전달받은 데이터를 사용하여, 실제 비즈니스 로직을 수행합니다. (지금은 메모리 기반의 간단한 데이터 조작)
// movies.controller.ts
@Controller('movies')
export class MoviesController {
  constructor(private readonly moviesService: MoviesService) {}

  @Get()
  getAll() {
    return this.moviesService.getAll();
  }
  // ... 다른 메서드들 ...
}

// movies.service.ts
@Injectable()
export class MoviesService {
  private movies: Movie[] = []; // 임시 데이터베이스 역할

  getAll(): Movie[] {
    return this.movies;
  }
  // ... 다른 비즈니스 로직 ...
}

✅ 3. 데이터베이스 연동: TypeORM

  • TypeORM은 TypeScript와 JavaScript를 위한 ORM(Object-Relational Mapper) 라이브러리입니다. ORM을 사용하면, SQL 쿼리를 직접 작성하지 않고도 객체(Object)와 메서드를 통해 데이터베이스를 조작할 수 있습니다. NestJS는 TypeORM과의 통합을 공식적으로 지원합니다.

➕ 3-1. TypeORM 설정

  1. 필요한 패키지 설치:

    npm install @nestjs/typeorm typeorm mysql2
    • @nestjs/typeorm: NestJS와 TypeORM을 연결하는 모듈.
    • typeorm: TypeORM 코어 라이브러리.
    • mysql2: 사용할 데이터베이스(MySQL/MariaDB)의 드라이버.
  2. 루트 모듈(app.module.ts)에 연결 정보 설정:

    • TypeOrmModule.forRoot()를 사용하여 애플리케이션 전체의 데이터베이스 연결 정보를 설정합니다. 이 정보는 보통 환경 변수를 통해 관리하는 것이 안전합니다.
    // app.module.ts
    import { TypeOrmModule } from '@nestjs/typeorm';
    
    @Module({
      imports: [
        TypeOrmModule.forRoot({
          type: 'mysql',
          host: 'localhost',
          port: 3306,
          username: 'root',
          password: 'password',
          database: 'nest_db',
          entities: [__dirname + '/**/*.entity{.ts,.js}'], // 엔티티 파일 자동 로드
          synchronize: true, // 개발용: 엔티티 변경 시 DB 스키마 자동 동기화
        }),
      ],
      // ...
    })
    export class AppModule {}
    • synchronize: true: 매우 편리한 개발용 옵션이지만, 데이터가 손실될 수 있으므로 운영 환경에서는 절대 사용하면 안 됩니다.

✅ 4. 엔티티(Entity)와 리포지토리(Repository)

➕ 4-1. 엔티티 (Entity)

  • 역할: 데이터베이스의 테이블 구조를 정의하는 클래스입니다. @Entity() 데코레이터와 @Column(), @PrimaryGeneratedColumn() 등의 데코레이터를 사용하여 테이블과 컬럼을 매핑합니다.

    // movie.entity.ts
    import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
    
    @Entity() // 이 클래스가 DB 테이블과 매핑됨을 선언
    export class Movie {
      @PrimaryGeneratedColumn() // 기본 키 (Auto-increment)
      id: number;
    
      @Column()
      title: string;
    
      @Column()
      year: number;
    }

➕ 4-2. 리포지토리 (Repository)

  • 역할: 엔티티에 대한 데이터베이스 CRUD(Create, Read, Update, Delete) 작업을 수행하는 저장소 패턴(Repository Pattern)의 구현체입니다.

  • 사용법:

    1. 기능 모듈(e.g., movies.module.ts)의 imports 배열에 TypeOrmModule.forFeature([Movie])를 추가하여, 해당 모듈에서 Movie 엔티티의 리포지토리를 사용할 수 있도록 등록합니다.
    2. 서비스의 생성자에서 @InjectRepository(Movie) 데코레이터를 사용하여 Movie의 리포지토리를 의존성 주입(DI) 받습니다.
    // movies.service.ts
    import { Injectable } from '@nestjs/common';
    import { InjectRepository } from '@nestjs/typeorm';
    import { Repository } from 'typeorm';
    import { Movie } from './entities/movie.entity';
    
    @Injectable()
    export class MoviesService {
      constructor(
        @InjectRepository(Movie) // Movie 엔티티의 리포지토리를 주입받음
        private readonly movieRepository: Repository<Movie>,
      ) {}
    
      async getAll(): Promise<Movie[]> {
        // 리포지토리의 메서드를 사용하여 DB와 상호작용
        return this.movieRepository.find();
      }
      // ... create, findOne, update, delete 등 ...
    }

📌 요약

  • NestJS CLIgenerate resource 명령어는 모듈, 컨트롤러, 서비스 등 기능 개발에 필요한 파일들을 자동으로 생성해줍니다.
  • TypeORM은 SQL 대신 객체와 메서드로 데이터베이스를 다룰 수 있게 해주는 ORM 라이브러리입니다.
  • 데이터베이스 연동은 app.module.tsTypeOrmModule.forRoot()로 연결 정보를 설정하는 것부터 시작합니다.
  • @Entity() 데코레이터로 DB 테이블을, @InjectRepository()Repository 객체를 통해 해당 테이블의 데이터 조작을 수행합니다.
  • 이제 서비스 계층은 메모리가 아닌, 주입받은 리포지토리를 통해 실제 데이터베이스와 상호작용하여 비즈니스 로직을 처리하게 됩니다.

0개의 댓글