2025년 1월 27일

김동환·2025년 1월 27일

TIL: NestJS CommentsController 코드 분석

오늘은 NestJS로 작성된 CommentsController 코드를 분석하며 학습한 내용을 정리합니다.


1. 컨트롤러 구조와 주요 의존성

CommentsController@nestjs/common에서 제공하는 데코레이터들을 활용하여 REST API를 구성한 컨트롤러입니다. 주요 특징은 다음과 같습니다:

  • 의존성 주입: 생성자에서 CommentsService를 주입받아 비즈니스 로직을 처리합니다.
  • 라우팅 데코레이터: @Post, @Get, @Patch, @Delete 등을 사용하여 HTTP 메서드와 경로를 매핑합니다.

2. 각 메서드의 역할

(1) 댓글 생성: createComment
  • 경로: POST /comments/:cardId
  • 설명: cardId로 특정 카드를 지정하고, 요청 바디에 담긴 content를 통해 새로운 댓글을 생성합니다.
  • 핵심 코드:
    await this.commentsService.createComment(cardId, 1, createCommentDto.content);
    현재 1로 하드코딩된 부분은 유저 ID를 나타내며, 이후 실제 사용자 인증 정보(user.id)로 대체해야 합니다.
(2) 댓글 조회: findAllComment
  • 경로: GET /comments/:cardId
  • 설명: 특정 카드(cardId)에 연결된 모든 댓글을 조회합니다.
  • 핵심 코드:
    return await this.commentsService.getCommentByCardId(cardId);
(3) 댓글 수정: updateComment
  • 경로: PATCH /comments/:id
  • 설명: 댓글 ID(id)와 요청 바디(content)를 받아 댓글 내용을 수정합니다.
  • 핵심 코드:
    await this.commentsService.updateComment(+id, 1, updateCommentDto.content);
    여기서도 1은 현재 하드코딩된 유저 ID로, 나중에 사용자 인증을 추가해야 합니다.
(4) 댓글 삭제: deleteComment
  • 경로: DELETE /comments/:id
  • 설명: 댓글 ID(id)를 받아 해당 댓글을 삭제합니다.
  • 핵심 코드:
    await this.commentsService.deleteComment(+id, 1);

3. 학습 포인트

  1. NestJS의 데코레이터 활용

    • @Controller: 컨트롤러의 기본 경로를 지정합니다.
    • @Param: URL 경로 매개변수를 바인딩합니다.
    • @Body: 요청 본문의 데이터를 바인딩합니다.
  2. 서비스 분리

    • 컨트롤러는 비즈니스 로직을 직접 수행하지 않고, CommentsService를 호출하여 처리합니다.
  3. 유저 인증 처리 필요성

    • 주석 처리된 부분(@userInfo)은 사용자 인증 정보를 활용해야 하는 영역을 보여줍니다. 현재는 임시로 하드코딩된 유저 ID(1)로 대체된 상태입니다.
  4. 코드 확장성

    • 추가적으로, 단일 댓글을 조회하는 기능(findOneComment)과 관련된 주석 코드가 존재하며, 이는 필요에 따라 확장할 수 있음을 나타냅니다.

4. 느낀 점

NestJS는 데코레이터와 DI(의존성 주입) 구조를 기반으로 명확한 코드 작성이 가능하다는 것을 다시 한번 느꼈습니다. 그러나 실제 인증 및 권한 관리와 같은 추가 작업이 필요하므로, 이를 염두에 두고 코드를 개선해야 할 것 같습니다.


comments.controller.ts

import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Patch,
  Post,
} from '@nestjs/common';
import { CommentsService } from './comments.service';
import { CreateCommentDto } from './dto/create-comment.dto';
import { UpdateCommentDto } from './dto/update-comment.dto';
// import { userInfo } from 'os'; 유저 엔티티에서 정보를 가져와야 한다.

@Controller('comments')
export class CommentsController {
  constructor(private readonly commentsService: CommentsService) {}

  @Post(':cardId')
  async createComment(
    // @userInfo() user: User,
    @Param('cardId') cardId: number,
    @Body() createCommentDto: CreateCommentDto,
  ) {
    await this.commentsService.createComment(
      cardId,
      1,
      createCommentDto.content,
    );
    // await this.commentsService.createComment(cardId, createCommentDto.content, user.id);
  }

  @Get(':cardId')
  async findAllComment(@Param('cardId') cardId: number) {
    return await this.commentsService.getCommentByCardId(cardId);
  }

  // @Get(':id/detail')
  // async findOneComment(@Param('id') id: number) {
  //   return await this.commentsService.getCommentById(+id);
  // }

  @Patch(':id')
  async updateComment(
    // @userInfo() user: User,
    @Param('id') id: number,
    @Body() updateCommentDto: UpdateCommentDto,
  ) {
    await this.commentsService.updateComment(+id, 1, updateCommentDto.content); //user.id
  }

  @Delete(':id')
  async deleteComment(
    // @userInfo() user: User,
    @Param('id') id: number,
  ) {
    await this.commentsService.deleteComment(+id, 1);
  }
}
profile
Node.js 7기

0개의 댓글