프로그래밍/Nest.js

Nest.js에서 데이터베이스 연결: 리포지토리 패턴 및 서비스의 중요성

shimdh 2025. 3. 20. 10:47
728x90

Nest.js 애플리케이션에서 데이터 저장 및 관리의 중요성은 아무리 강조해도 지나치지 않습니다. 데이터베이스는 애플리케이션의 핵심 요소로, 사용자와의 상호작용을 통해 생성되는 모든 정보를 안전하게 저장하고 효율적으로 관리하는 역할을 합니다. 본 포스트에서는 Nest.js에서 데이터베이스 연결을 위한 리포지토리 패턴과 서비스의 중요성에 대해 깊이 있게 살펴보겠습니다.

데이터베이스와 Nest.js

Nest.js는 TypeORM과 Mongoose와 같은 강력한 ORM(Object-Relational Mapping) 라이브러리를 지원하여 개발자가 데이터베이스와 원활하게 상호작용할 수 있도록 돕습니다. 이러한 도구들은 데이터베이스와의 연결을 단순화하고, 복잡한 쿼리 작성 과정을 최소화하여 개발자의 생산성을 높여줍니다.

TypeORM 및 Mongoose 설정

TypeORM

  • TypeORM은 관계형 데이터베이스를 다루기 위한 ORM으로, MySQL, PostgreSQL 등 SQL 기반의 데이터베이스에 최적화되어 있습니다. TypeORM은 데이터베이스의 구조를 코드로 정의할 수 있게 해주며, 이를 통해 데이터베이스와의 상호작용을 더욱 직관적으로 만들어 줍니다.

Mongoose

  • Mongoose는 MongoDB와 함께 사용되는 ODM(Object Document Mapper)으로, NoSQL 데이터베이스에 적합합니다. Mongoose는 스키마 기반의 데이터 모델링을 지원하여 데이터의 구조를 명확히 정의하고, 데이터 유효성을 검증하는 데 유용합니다.

이 두 가지 라이브러리 중 하나를 선택하여 프로젝트에 통합할 수 있으며, 각 라이브러리의 특성에 따라 적절한 선택이 필요합니다.

MySQL 데이터베이스 연결 설정 예시

TypeORM을 사용할 경우 다음과 같은 설정을 통해 MySQL 데이터베이스에 연결할 수 있습니다:

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'test',
      password: 'test',
      database: 'test_db',
      entities: [__dirname + '/**/*.entity{.ts,.js}'],
      synchronize: true,
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

위 코드는 MySQL 데이터베이스에 연결하기 위한 기본 설정을 보여줍니다. 이 설정을 통해 애플리케이션은 데이터베이스와의 연결을 수립하고, 데이터의 CRUD(Create, Read, Update, Delete) 작업을 수행할 수 있는 기반을 마련합니다.

리포지토리 패턴

리포지토리 패턴은 도메인 모델과 데이터 매핑 계층 간의 의존성을 줄이기 위해 사용하는 디자인 패턴입니다. 이 패턴을 통해 비즈니스 로직에서 데이터 접근 코드가 분리되어 유지보수가 용이해지며, 코드의 가독성과 재사용성을 높일 수 있습니다.

리포지토리 생성

Nest.js에서는 @InjectRepository 데코레이터를 사용하여 리포지토리를 주입받아 사용할 수 있습니다. 아래는 사용자(User) 엔티티에 대한 리포지토리를 생성하는 예시입니다.

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 findAll(): Promise<User[]> {
    return this.userRepository.find();
  }

  async create(userData): Promise<User> {
    const user = this.userRepository.create(userData);
    return this.userRepository.save(user);
  }
}

위 코드는 UserService 클래스 내에서 User 엔티티에 대한 CRUD 작업을 수행하는 메소드들을 정의한 것입니다. 이 메소드들은 사용자 데이터를 효율적으로 관리하고, 애플리케이션의 비즈니스 로직을 구현하는 데 중요한 역할을 합니다.

서비스

서비스는 비즈니스 로직을 처리하는 구성 요소로서, 컨트롤러와 리포지토리 사이의 중개 역할을 합니다. 서비스 내에서는 다양한 기능들을 조합하여 복잡한 비즈니스 로직을 구현할 수 있으며, 이를 통해 코드의 구조를 더욱 명확하게 유지할 수 있습니다.

서비스 예시

예를 들어 게시물(Post)을 관리하는 서비스를 작성한다고 가정해 보겠습니다:

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

@Injectable()
export class PostService {
  constructor(
    @InjectRepository(Post)
    private postRepository: Repository<Post>,
  ) {}

  async findPostById(id): Promise<Post> {
    return await this.postRepository.findOne(id);
  }

  async updatePost(id, updateData): Promise<Post> {
    await this.postRepository.update(id, updateData);
    return this.findPostById(id);
  }
}

위 코드는 특정 ID로 게시물을 검색하고 업데이트하는 기능을 제공하며, 이는 실제 애플리케이션에서 자주 사용되는 일반적인 동작입니다. 이러한 서비스는 게시물 관리와 관련된 다양한 비즈니스 로직을 처리할 수 있도록 설계되어 있습니다.

결론

데이터베이스 연결 및 리포지토리 패턴은 Nest.js 애플리케이션 개발 시 중요한 개념들입니다. 이러한 구조 덕분에 코드가 더 깔끔하고 이해하기 쉬워져 팀원 간 협업도 원활하게 이루어질 수 있습니다. 실무에서도 이러한 방식으로 데이터를 처리하면 효율적이고 관리하기 쉬운 코드를 작성할 수 있게 됩니다. 데이터베이스와의 연결을 통해 애플리케이션의 성능을 극대화하고, 비즈니스 로직을 효과적으로 구현함으로써, 사용자에게 더 나은 경험을 제공할 수 있습니다.

728x90