Express는 Node.js 기반의 웹 프레임워크로 백엔드, 즉 서버 구축을 위한 것이다.
JAVA - Spring, Python - Django가 거의 당연하게 연결되듯이 Node.js하면 Express를 떠올리게 된다.
프레임워크란 간단히 말하자면 App을 만들기 위해 다양하고 편리한 라이브러리/미들웨어 등이 내장된 Package를 말한다. 이를 통해 개발에 있어 효율성이 오르며, 개발 규칙에 의해 코드 구조의 통일성이 향상된다는 장점이 있다.
Prisma는 이전 포스팅에서 설명한 ORM 중 하나다.(이전 포스팅 참고)
해당 기능을 구현한 프로젝트에서 DBMS로 Mysql을 활용하였기 때문에 개발의 편의성을 위해 Prisma를 채택하였다.
model Comment {
id String @id @default(uuid())
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
authorId String
diary Diary @relation(fields: [diaryId], references: [id], onDelete: Cascade)
diaryId String
content String
nestedComment String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
reply Comment? @relation("comment", fields: [nestedComment], references: [id], onDelete: Cascade)
reComment Comment[] @relation("comment")
}
commentRouter.post('/:diaryId', jwtAuthentication, createComment);
commentRouter.get('/:diaryId', getComment);
commentRouter.put('/:commentId', jwtAuthentication, updateComment);
commentRouter.delete('/:commentId', jwtAuthentication, deleteComment);
export const createComment = async (
req: IRequest,
res: Response,
next: NextFunction,
) => {
try {
const authorId = req.user.id;
const inputData = req.body;
const diary_id: string = req.params.diaryId;
const comment = await createdComment(inputData, authorId, diary_id);
res.json(comment);
} catch (error) {
next(error);
}
};
export const getComment = async (
req: Request,
res: Response,
next: NextFunction,
) => {
try {
const diary_id: string = req.params.diaryId;
const page = Number(req.query.page) || 1;
const limit = Number(req.query.limit) || 8;
const comment = await getCommentByDiaryId(diary_id, page, limit);
res.json(comment);
} catch (error) {
next(error);
}
};
export async function createdComment(
inputData: {
content: string;
nestedComment: string;
},
authorId: string,
diary_id: string,
) {
try {
const { content, nestedComment } = inputData;
const comment = await prisma.comment.create({
data: { diaryId: diary_id, authorId, content, nestedComment },
});
const commentResponseData = plainToClass(commentResponseDTO, comment, {
excludeExtraneousValues: true,
});
const response = successApiResponseDTO(commentResponseData);
return response;
} catch (error) {
throw error;
}
}
// 댓글 조회
export async function getCommentByDiaryId(
diary_id: string,
page: number,
limit: number,
) {
try {
const comment = await prisma.comment.findMany({
skip: (page - 1) * limit,
take: limit,
where: { diaryId: diary_id, nestedComment: null },
select: {
id: true,
author: {
select: {
id: true,
username: true,
profileImage: true,
},
},
diaryId: true,
content: true,
createdAt: true,
updatedAt: true,
reComment: {
select: {
id: true,
author: {
select: {
id: true,
username: true,
profileImage: true,
},
},
diaryId: true,
content: true,
createdAt: true,
updatedAt: true,
},
},
},
orderBy: { createdAt: 'asc' },
});
if (comment.length == 0) {
const response = emptyApiResponseDTO();
return response;
}
const { totalComment, totalPage } = await calculatePageInfoForComment(
limit,
diary_id,
);
const pageInfo = { totalComment, totalPage, currentPage: page, limit };
const commentResponseDataList = comment.map((comment) =>
plainToClass(commentResponseDTO, comment, {
excludeExtraneousValues: true,
}),
);
const response = new PaginationResponseDTO(
200,
commentResponseDataList,
pageInfo,
'성공',
);
return response;
} catch (error) {
throw error;
}
}
댓글 작성
prisma.comment.create를 통해 comment 테이블에 댓글 정보 저장
해당 코드에서 DTO를 적용했는데 DTO(Data Transfer Object)는 간단히 말하자면 정보를 노출시키지 않고 데이터를 주고받기 위한 객체이다.
댓글 조회
prisma.comment.findMany를 이용하여 원하는 댓글정보 조회
skip, take는 pagenation을 위한 속성
where는 어떤 정보를 찾을 것인지임(nestedComment: null 인 이유는 대댓글의 경우, 댓글 내부에서 불러올 것이므로 대댓글 중복 조회 방지를 위함)
select은 조회된 댓글에서 어떤 속성을 응답할 것인지를 정하는 것
author는 user와 연결되어 있기 때문에 author.id = user.id 인 데이터를 user 테이블에서 찾음
reComment는 self join으로 대댓글을 조회하기 위한 속성임
댓글 조회
- 댓글 내부에 reComment 속성으로 대댓글이 조회되는 것을 확인
이번 프로젝트에서 댓글 기능을 구현해보면서 pagenation, self join 등 처음 구현해본 것들이 꽤 있었다.
개념으로는 어느정도 알고 있었지만 역시 직접 손으로 코드를 작성하고 구현해봐야 제대로된 이해를 할 수 있다는 것을 다시 한번 깨달을 수 있었던 기회였다.
앞으로도 무언가를 보고 끄덕이지만 말고 직접 손으로 구현해봐야겠다라는 다짐을 하게된다.
그리고 코드 작성할때 머리를 아프게하는 경우들이.... 존재하지만 이를 해결하고 작동되는 것을 보니 짜릿한 쾌감이 느껴지는게... 코딩은 계속해서 나를 끌어당기는 매력이 있다는 것을 또한번 느끼게 되었다...