본문 바로가기
Research/Nest.js

nestjs_repository 추가하기

by RIEM 2023. 4. 6.

현재 Controller, Service 두 레이어만 있는 상황인데, 리파지토리 레이어를 추가하여 DB 관련 작업을 추상화시켜주자. 추후 여분의 DB를 연결하거나 또 다른 모듈에서 해당 모듈의 DB 관련 로직을 수행해야할 경우 편리하다. 왜냐하면 기능이 추상화되어있기에 메소드만 사용하면 되기 때문이다.

 

Module에 리파지토리 레이어 프로바이더 등록

당연하지만 Repository 레이어를 사용하려면 Module에도 등록을 먼저 해야한다. 그냥 모듈은 동사무소 같은 곳이다. 리파지토리는 공급되는 Provider 역할을 하기에 providers 프로퍼티에 추가해준다.

// cats.module
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { MongooseModule } from '@nestjs/mongoose';
import { Cat, CatSchema } from './cats.schema';
import { CatsRepository } from './cats.repository';

@Module({
  // Schema 사용을 위한 등록import
  imports: [MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }])],
  controllers: [CatsController],
  providers: [CatsService, CatsRepository],
  exports: [CatsService], //캡슐화된 것을 공개
})
export class CatsModule {}

 

Service 레이어

// cats.service

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import * as bcrypt from 'bcrypt';
import { Cat } from './cats.schema';
import { CatRequestDto } from './dto/cats.request.dto';
import { CatsRepository } from './cats.repository';

@Injectable()
export class CatsService {
  // repository 생성자 주입
  constructor(private readonly catsRepository: CatsRepository) {}

  async signUp(body: CatRequestDto) {
    const { email, name, password } = body;

    // 주입받은 리파지토리의 existsByEmail 메소드 사용
    const isCatExist = await this.catsRepository.existsByEmail(email);

    if (isCatExist) {
      throw new UnauthorizedException('해당하는 고양이는 이미 존재합니다.');
    }
    // 비밀번호 해시화
    const hashedPassword = await bcrypt.hash(password, 10);

    // DB 저장
    const cat = await this.catsRepository.create({
      email,
      name,
      password: hashedPassword,
    });

    // virtual field로 반환하여 비밀번호 숨김처리
    return cat.readOnlyData;
  }
}

 

Repository 레이어

// cats.repository.ts

import { HttpException, Injectable } from '@nestjs/common';
import { Cat } from './cats.schema';
import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { CatRequestDto } from './dto/cats.request.dto';

@Injectable()
export class CatsRepository {
  // Cat mongoose 스키마 생성자 주입
  // 만약, DB를 추가하고 싶으면 추가로 생성자에 주입해주면 된다
  constructor(@InjectModel(Cat.name) private readonly catModel: Model<Cat>) {}

  // * 이메일 존재 여부 확인
  async existsByEmail(email: string): Promise<boolean> {
    try {
      const result = await this.catModel.exists({ email });
      if (result) return true;
      else return false;
    } catch (error) {
      throw new HttpException('db error', 400);
    }
  }

  // * 유저 생성
  async create(cat: CatRequestDto): Promise<Cat> {
    return await this.catModel.create(cat);
  }
}

 

댓글