github-blog.png


โœ๏ธ Today I Learned


  • ์ตœ๊ทผ NestJS + TypeORM ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ์„œ๋ฒ„๋ฅผ ๊ตฌ์„ฑํ•˜๋ฉฐ ๊ณต๋ถ€ํ•˜๊ณ ์žˆ๋‹ค.

  • TypeORM์ด Repository Pattern์„ ๊ธฐ๋ณธ์œผ๋กœ ์ง€ํ–ฅํ•˜๊ณ  ์ง€์›ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ NestJS ๊ณต์‹ ๋ฌธ์„œ์—๋„ Repository Pattern์„ ์ด์šฉํ•œ ์„ค๊ณ„ ๋ฐฉ์‹์„ ์•ˆ๋‚ดํ•˜๊ณ  ์žˆ๋‹ค.

  • ๋‚˜ ๋˜ํ•œ ํ˜„์žฌ ์ง„ํ–‰ ์ค‘์ธ ํ”„๋กœ์ ํŠธ์— ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฝ๊ณ  Repository Pattern๋ฅผ ์ ์šฉํ•ด์„œ ๊ฐœ๋ฐœ์„ ์ด์–ด๋‚˜๊ฐ€๊ณ  ์žˆ๋‹ค.

  • ๋ฌธ๋“ Repository Pattern๊ฐ€ ๋ฌด์—‡์ด๊ณ  ์™œ ์“ฐ๋Š”๊ฑฐ์ง€? ๊ฐ€ ๊ถ๊ธˆํ•ด์กŒ๊ณ  ๊ทธ ๊ณผ์ •์„ ๊ธ€๋กœ ๋‚จ๊ฒจ๋ณด๋ คํ•œ๋‹ค.



1. Repository Pattern


  • ์šฐ์„  Repository Pattern์€ ์—ฌ๋Ÿฌ ๋””์ž์ธ ํŒจํ„ด ์ค‘ ํ•˜๋‚˜์ด๋‹ค.

    overview-1

  • ๋‚ด๊ฐ€ ์ดํ•ดํ•œ(?)๋Œ€๋กœ ๋งํ•˜์ž๋ฉด ์‹ค์ œ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ์žฅ์†Œ๋ฅผ ์ถ”์ƒํ™”ํ•˜์—ฌ Repository๋กœ ๋‘” ๋’ค, ํ•ด๋‹น ์žฅ์†Œ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ๊ฐ€๊ณตํ•˜๋Š” ์—…๋ฌด๋ฅผ ์ „๋‹ดํ•œ๋‹ค.

  • ๊ทธ๋ ‡๊ธฐ์— ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ์ถœ์ฒ˜(Local, Remote)๋ผ๋˜์ง€, ์›๋ณธ ๋ฐ์ดํ„ฐ ์†์„ฑ๋“ฑ์„ ์•Œ์•„์•ผํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

  • ๊ทธ์ € ํŠน์ • ์š”์ฒญ์„ Repository์— ๋ณด๋‚ด๋ฉด ๊ฐ€๊ณต๋œ ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ ์–ป์„ ์ˆ˜ ์žˆ๊ฒŒ๋” ๋””์ž์ธ ํŒจํ„ด์„ ์„ค๊ณ„ํ•˜๋Š” ๊ตฌ์กฐ๊ฐ€ Repository Pattern์ด๋‹ค.



2. ์‹ค์ œ ํ”„๋กœ์ ํŠธ ์ ์šฉ ์˜ˆ์‹œ


  • ์šฐ์„  NestJS ํ”„๋ ˆ์ž„์›Œํฌ ๊ฐ•์˜๋ฅผ ๋“ค์œผ๋ฉฐ ์ž‘์„ฑํ•œ Repository Pattern์ด ์ ์šฉ๋œ ์ƒ˜ํ”Œ ์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์™”๋‹ค.

    • boards.service.ts

      @Injectable()
      export class BoardsService {
        constructor(
          @InjectRepository(BoardRepository)
          private boardRepository: BoardRepository,
        ) {}
      
        /* ์ „๋‹ฌ์ธ์ž๋กœ CreateBoardDTO๋ฅผ ๊ฐ–๋Š” ๋ณด๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” createBoard ๋ฉ”์„œ๋“œ ์„ ์–ธ */
        createBoard(createBoardDto: CreateBoardDto): Promise<Board> {
          return this.boardRepository.createBoard(createBoardDto); // Repository ํŒจํ„ด ์ ์šฉ
        }
      
      ...
    • boards.repository.ts

      /* Board Entity๋ฅผ ์ปจํŠธ๋กคํ•˜๋Š” Repository๋ฅผ ์„ ์–ธ */
      @EntityRepository(Board)
      export class BoardRepository extends Repository<Board> {
        /* createBoard ๋ฉ”์„œ๋“œ, DB ๊ด€๋ จ ๋™์ž‘์€ Repository์—์„œ ์ˆ˜ํ–‰ํ•œ๋‹ค */
        async createBoard(createBoardDto: CreateBoardDto): Promise<Board> {
          /* title๊ณผ description์€ ๊ตฌ์กฐ๋ถ„ํ•ด ํ• ๋‹น์œผ๋กœ createBoardDto์—์„œ ๊บผ๋‚ด์–ด์„œ ์‚ฌ์šฉํ•ด์ค€๋‹ค */
          const { title, description } = createBoardDto;
          const board = this.create({
            title,
            description,
            status: BoardStatus.PUBLIC, // status๊ฐ’์€ BoardStatus.PUBLIC์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค
          });
          await this.save(board); // board๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ
          return board; // DB์— ์ €์žฅํ•œ board๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค
        }
      }
  • ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ์ง€๋งŒ Repository Pattern์ด ์ ์šฉ๋œ ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

  • ๋ฐ์ดํ„ฐ๋ฅผ ์›๋ณธ ์ €์žฅ์†Œ์—์„œ ๊บผ๋‚ด์˜จ ๋’ค ๊ฐ€๊ณตํ•ด์„œ ์ œ๊ณตํ•˜๋Š” ์žฅ์†Œ(boards.repository.ts)์™€ ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์žฅ์†Œ(boards.service.ts)๋ฅผ ๋ถ„๋ฆฌ์‹œํ‚จ ๋””์ž์ธ ํŒจํ„ด์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

  • TypeORM์—์„œ ๊ธฐ๋ณธ์œผ๋กœ Repository Pattern์„ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์œ„์™€ ๊ฐ™์€ ๋””์ž์ธ ํŒจํ„ด์„ NestJS + TypeORM ํ”„๋ ˆ์ž„์›Œํฌ ์ƒํƒœ๊ณ„์—์„œ๋Š” ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.



3. Repository Pattern์˜ ์žฅ์ ?


  • ์šฐ์„  ์–ด๋–ค ๊ฐœ๋…์ด๊ณ , ์–ด๋–ป๊ฒŒ ์“ฐ์ด๋Š”์ง€๋Š” ์•Œ์•˜์œผ๋‹ˆ ์žฅ์ ์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ฐพ์•„๋ณด์•˜๋‹ค.

    • ๋ฐ์ดํ„ฐ ๋กœ์ง์„ ๋ถ„๋ฆฌ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

      โ‡’ ํŒŒ์ผ ๊ตฌ์กฐ๋ถ€ํ„ฐ ๋ถ„๋ฆฌ๊ฐ€ ๋œ๋‹ค.

    • ์ค‘์•™ ์ง‘์ค‘์ฒ˜๋ฆฌ ๋ฐฉ์‹์œผ๋กœ, ์–ธ์ œ๋‚˜ ์ผ๊ด€๋œ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋‹ค.

      โ‡’ ์š”์ฒญ์„ ํ•˜๋Š” ์ชฝ์€ Repository์˜ ์‚ฌ์ •์ด ๊ถ๊ธˆํ•˜์ง€๋„ ํ•„์š”ํ•˜์ง€๋„ ์•Š๋‹ค. ์–ธ์ œ๋‚˜ ํ•ญ์ƒ ๊ฐ™์€ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์š”์ฒญ์„ํ•˜๊ณ  ๊ฒฐ๊ณผ๊ฐ’์„ ์ œ๊ณต๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

    • ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ๊ฒ€์ฆ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

      โ‡’ ํ…Œ์ŠคํŠธ ๊ฒฝํ—˜์€ ์—†์ง€๋งŒ, ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•˜๊ณ  ์ œ๊ณตํ•˜๋Š” Repository์—์„œ๋งŒ ๊ฒ€์ฆ์„ ์ถ”๊ฐ€ํ•œ๋‹ค๋ฉด ์‘๋‹ต์œผ๋กœ ๋ฐ˜ํ™˜๋  ๋ฐ์ดํ„ฐ๊ฐ’๋“ค์„ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๋จผ์ € ์ ์šฉ์‹œ์ผœ ๊ฒ€์ฆ์ด ์ˆ˜์›”ํ•  ๊ฑฐ ๊ฐ™๋‹ค๋ผ๋Š” ์ƒ๊ฐ์€ ๋“ ๋‹ค.

    • ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ ๋กœ์ง ์ฝ”๋“œ๋ฅผ ์‰ฝ๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

      โ‡’ Repository์—์„œ๋งŒ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋กœ์ง์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํฐ ์žฅ์ ์ด๋‹ค.



๐Ÿค” Understanding

  • ๊ทธ๋ƒฅ NestJS ๊ณต์‹ ๋ฌธ์„œ์—์„œ ์“ฐ๋ผํ•ด์„œ ์ผ๊ณ , TypeORM์—์„œ ๊ธฐ๋ณธ์œผ๋กœ ์ง€์›ํ•ด์ฃผ๋‹ˆ ์“ฐ๋˜ Repository Pattern์„ ๊ทธ๋‚˜๋งˆ ์กฐ๊ธˆ ์ดํ•ดํ•˜๊ณ  ์จ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

  • ์•ž์œผ๋กœ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•˜๊ฑฐ๋‚˜ ๊ฐ€์ ธ์˜ค๋Š” ๋กœ์ง์„ ํ™•์‹คํžˆ Repository ์˜์—ญ์—์„œ ์ˆ˜ํ–‰ํ•ด์ฃผ๋Š” ์ชฝ์œผ๋กœ ์กฐ๊ธˆ ๋” ์ƒ๊ฐํ•œ ๋’ค ์ฝ”๋“œ๋กœ ์˜ฎ๊ฒจ๊ฐ€์•ผ๊ฒ ๋‹ค~ ๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

-๊ทœ๋ชจ๊ฐ€ ํฐ ํ”„๋กœ์ ํŠธ์ผ์ˆ˜๋ก ๋””์ž์ธ ํŒจํ„ด๋“ฑ ๊ตฌ์กฐ ์„ค๊ณ„๋ถ€ํ„ฐ ์ค‘์š”ํ• ๊ฑฐ๊ฐ™๋‹ค๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค.