본문 바로가기
Back-end/기초부터 따라하는 nest.js

#11-1. 기초부터 따라하는 Nest.js : Comment CRUD

by hsloth 2023. 5. 15.

 

해당 포스팅은 nest.js 9.0.0 버전, typeorm 0.3.x 버전을 기준으로 작성되었습니다.
모든 글은 작성자의 주관이 100% 담겨있기 때문에 부정확할 수 있습니다.

#pre. 터미널을 켜고 프로젝트 폴더로 이동

https://suloth.tistory.com/44

 

#0-1. 기초부터 따라하는 nest.js : 터미널 키는 법 + 터미널에서 작업 폴더 이동

윈도우 윈도우는 윈도우+R 버튼을 누른 후, cmd 를 입력하여 터미널을 킵니다. 혹은 윈도우 버튼을 눌러서 검색창에 cmd를 검색하면 터미널이 나올텐데 그걸 실행시켜주시면 됩니다. Mac OS Mac의 경

suloth.tistory.com

 
위의 링크의 내용을 참고하여 study 폴더로 이동해줍니다.
그리고 code . 명령어를 통해 vscode를 열어줍니다.


지난 포스팅에서 Article에 대한 CRUD를 작성했습니다.

https://suloth.tistory.com/92

 

#11. 기초부터 따라하는 Nest.js : Article CRUD

해당 포스팅은 nest.js 9.0.0 버전, typeorm 0.3.x 버전을 기준으로 작성되었습니다. 모든 글은 작성자의 주관이 100% 담겨있기 때문에 부정확할 수 있습니다. #pre. 터미널을 켜고 프로젝트 폴더로 이동 ht

suloth.tistory.com

 

이번 포스팅에서는 Comment 관련 CRUD를 구현해보도록 하겠습니다.

지난 포스팅에서 전반적인 설명을 다 하였으니, 이번 포스팅에서는 각자 어느정도 알아서 해보셨으면 좋겠다는 마음에 순서 설명만 하면서 진행해보겠습니다. 제 설명을 따라가면서 천천히 코드를 작성해 보시기 바랍니다. 최종 코드는 각 단원 아래 쪽에 적어놓겠습니다!


Comment 기본 세팅


먼저, res 폴더 안에 comment 폴더를 만들어주고, comment.module.ts, comment.controller.ts, comment.service.ts 파일을 만들어 줍니다.

 

그리고 기본 코드를 작성해줍니다.

 

기본 코드를 작성했다면, AppModule에 CommentModule을 등록해줍시다.

 

최종코드

// comment.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { CommentEntity } from 'src/entities/comment.entity';
import { Repository } from 'typeorm';

@Injectable()
export class CommentService {
  constructor(
    @InjectRepository(CommentEntity)
    private readonly commentRepository: Repository<CommentEntity>,
  ) {}
}

// comment.controller.ts
import { Controller } from '@nestjs/common';
import { CommentService } from './comment.service';

@Controller('comment')
export class CommentController {
  constructor(private readonly commentService: CommentService) {}
}

// comment.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { CommentEntity } from 'src/entities/comment.entity';
import { CommentController } from './comment.controller';
import { CommentService } from './comment.service';

@Module({
  imports: [TypeOrmModule.forFeature([CommentEntity])],
  controllers: [CommentController],
  providers: [CommentService],
})
export class CommentModule {}

// app.module.ts
...
import { CommentModule } from './res/comment/comment.module';

@Module({
  imports: [
	...
    UserModule,
    AuthModule,
    ArticleModule,
    CommentModule, // Comment모듈이 추가되었습니다.
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

 


Create


 

Create를 위해서 두 가지를 해줍시다!

 

1. CommentService에 createComment 함수 만들기

  • commentRepository의 save함수를 사용해서 쿼리문을 날리고, 해당 결과 값을 리턴해줍시다.
  • 함수의 인자로 userId와 parentId, content, articleId가 필요합니다.

 

 

2. CommentController에 createComment 함수 만들기

  • Body로 content와 parentId, articleId를 받고, Guard로 로그인이 되어있을 경우에만 댓글을 달 수 있도록 하며, User데코레이터로 user를 받아서 user.id를 commentService쪽에 넘겨줍시다.
  • 함수의 인자로 body, user가 필요합니다.

 

그리고, 코드 작성을 완료했다면, 커밋을 해줍시다.

 

 

최종코드

// comment.service.ts
  @UseGuards(JwtAuthGuard)
  @Post()
  async createComment(@Body() body, @User() user) {
    const content = body.content;
    const parentId = body?.parentId; // 부모가 없는 경우는 undefined 리턴
    const articleId = body.articleId;
    const userId = user.id;

    const comment = await this.commentService.createComment(
      content,
      parentId,
      userId,
      articleId,
    );

    return comment;
  }

// comment.controller.ts
  async createComment(
    content: string,
    parentId: string,
    userId: string,
    articleId: string,
  ) {
    const comment = await this.commentRepository.save({
      content: content,
      userId: userId,
      parentId: parentId,
      articleId: articleId,
    });

    return comment;
  }

 


Read


댓글은 따로 Read하는 기능을 만들지 않겠습니다.

이 다음 포스팅에서 Article을 Read할 때, Comment를 join해서 read하는 방법을 배워보도록 할 예정입니다.

 


Update


Update를 위해서도 두 가지 함수를 작성해봅시다!

 

1. CommentService에 modifyComment 함수 만들기

  • commentRepository의 update 함수를 사용해서 updateResult를 받아오고,{ affected: updateResult?.affected }를 리턴합시다.
  • 함수의 인자로 commentId, userId, content가 필요합니다.

 

2. CommentController에 updateComment 함수 만들기

  • Body로 content를 받고, url의 Param으로 id를 받아서 commentId 변수에 할당합시다. 그리고 Guard를 이용해서 로그인을 확인하고, User데코레이터를 이용하여 userId를 구해서 본인의 댓글만 수정할 수 있도록 합니다. 
  • 함수의 인자로 body, user, id가 필요합니다.

 

그리고 코드 작성을 완료했다면, 커밋을 해줍시다.

 

 

최종코드

// comment.service.ts
  async modifyComment(commentId: string, userId: string, content: string) {
    const comment = await this.commentRepository.findOne({
      where: {
        id: commentId,
        userId: userId,
      },
    });

    if (!comment) {
      throw new UnauthorizedException('본인의 댓글이 아닙니다.');
    }

    const updateResult = await this.commentRepository.update(
      { id: commentId },
      { content: content },
    );

    return { affected: updateResult?.affected };
  }

// comment.controller.ts
  @UseGuards(JwtAuthGuard)
  @Put('/:id')
  async updateComment(@Body() body, @User() user, @Param('id') id) {
    const content = body.content;
    const userId = user.id;
    const commentId = id;

    const res = await this.commentService.modifyComment(
      commentId,
      userId,
      content,
    );

    return res;
  }

 


Delete


 

여기서도 두 가지 함수를 작성해줍시다.

 

1. CommentService에 removeComment 함수 만들기

  • commentRepository의 softDelete 함수를 사용해서 { affected: deleteResult?.affected } 리턴하기
  • 함수의 인자로 commentId와 userId가 필요합니다.

 

2. CommentController에 deleteComment 함수 만들기

  • Guard를 이용해 로그인을 확인하고 User데코레이터로 userId를 구하여 본인의 댓글만 삭제할 수 있도록 합니다. 그리고 url의 Param으로 id를 받아서 commentId 변수에 할당합니다. 
  • 함수의 인자로 id, user가 필요합니다.

 

코드를 다 작성했다면, 커밋을 해줍시다.

 

 

최종코드

// comment.service.ts
  async removeComment(commentId: string, userId: string) {
    const deleteResult = await this.commentRepository.softDelete({
      id: commentId,
      userId: userId,
    });

    return { affected: deleteResult?.affected };
  }

// comment.controller.ts
  @UseGuards(JwtAuthGuard)
  @Delete('/:id')
  async deleteComment(@Param('id') id, @User() user) {
    const commentId = id;
    const userId = user.id;

    const res = await this.commentService.removeComment(commentId, userId);

    return res;
  }

 


모든 작업이 끝났다면, Github에 푸쉬해줍시다.

 

https://suloth.tistory.com/46

 

#0-2. 기초부터 따라하는 Nest.js : Git과 Github 사용법

이 글은 아래의 포스팅에 이어서 작성하는 포스팅입니다. https://suloth.tistory.com/45 #1. 기초부터 따라하는 Nest.js : Nest.js 초기 설정 Nest.js란? node.js의 백엔드 프레임워크 중 하나입니다. node.js에는 수

suloth.tistory.com

 

참고하시라고 올려두는 사진입니다.