해당 포스팅은 nest.js 9.0.0 버전, typeorm 0.3.x 버전을 기준으로 작성되었습니다.
모든 글은 작성자의 주관이 100% 담겨있기 때문에 부정확할 수 있습니다.
#pre. 터미널을 켜고 프로젝트 폴더로 이동
위의 링크의 내용을 참고하여 study 폴더로 이동해줍니다.
그리고 code . 명령어를 통해 vscode를 열어줍니다.
지난 포스팅에서 Article에 대한 CRUD를 작성했습니다.
이번 포스팅에서는 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에 푸쉬해줍시다.
참고하시라고 올려두는 사진입니다.
'Back-end > 기초부터 따라하는 nest.js' 카테고리의 다른 글
#12. 기초부터 따라하는 Nest.js : Dto와 Swagger (0) | 2023.05.17 |
---|---|
#11-2. 기초부터 따라하는 Nest.js : Join (0) | 2023.05.15 |
#11. 기초부터 따라하는 Nest.js : Article CRUD (6) | 2023.05.11 |
#10-1. 기초부터 따라하는 Nest.js : User Decorator (0) | 2023.05.11 |
#10. 기초부터 따라하는 Nest.js : JWT 로그인 구현과 Guard(2) - 실전편 (17) | 2023.04.18 |