저번 포스팅에서 이야기한대로 이번 시간에는 직접 Comments 엔티티에 대한 Controller, Repository, Service를 만들어볼게요. 일단 아래에 Comment 엔티티가 추가된 코드의 깃허브 링크를 올려두었으니 참고해주세요.
>> Comment가 추가된 코드
이번인 두 가지 API를 설계해보았는데요. Post 요청으로 댓글을 작성하는 API와 Get 요청으로 특정 member의 댓글 기록을 조회하는 API입니다. 이번에도 구체적인 설명은 생략하고 새로운 개념에 대해서만 간략히 짚고 넘어갈게요.
Member는 Board와 일대다 관계를 맺고 있고, Board와 Comments도 다시 일대다 관계를 맺고 있다. 또한 Member와 Comments도 일대다 관계이다. 즉, Comments 테이블에는 Member와 Board 테이블의 기본키를 외래키로 사용하고 있는 것이다.
당연히 Member와 Board 클래스에서 Comment를 List로 관리해야 한다.
Member 클래스와 Comment 클래스의 관계는 일대다이므로, Comment가 주인이 되고, Member는 mappedBy될 것이다. Member 클래스 측에서는 Comment들을 List로 관리해야 한다.
Board 클래스와 Comment 클래스의 관계는 일대다이므로, Comment가 주인이 되고 Board는 mappedBy될 것이다. Board 클래스 측에서는 Comment들을 List로 관리해야 한다.
자세히 들여다 보면 못 보던 어노테이션이 있다. 바로 @RequestMapping 어노테이션인데, 이는 아래 컨트롤러에 정의된 모든 요청 URI에 "/comment"가 자동으로 추가된다는 의미 정도로 생각하면 된다. 쉽게 말해 댓글을 작성하는 API를 호출하려면, http://localhost:8080/comment를 입력해야 한다는 것이다.
Post 요청을 위해선 boardId와 email, reply가 Json 형식으로 요청 본문에 입력되어야 한다.
입력받은 boardId로는 게시글을 찾고, email로는 멤버를 찾아 comment를 빌드하고 있다.
이 API는 두 가지 버전으로 설계하였다.
멤버 ID를 받아 멤버와 댓글을 찾고 있다. 결과적으로는 댓글을 단 게시글의 제목과 댓글 내용이 List형태로 반환된다. 근데 이 API에는 문제점이 하나 있다. 무엇일까?
예를 들어 Chrome이라는 멤버가 여러 게시글에 댓글을 달았다고 해보자. 간혹 한 게시글에 여러 번 댓글을 다는 경우도 있었을 것이다.
Chrome이라는 멤버가 게시글 1,2,3번에 한번씩 댓글을 달고, 2번 게시글에 댓글을 한번 더 달았다. 이 때 list-up 요청에 대한 출력 결과는 아래와 같이 나타난다.
Hi! My Name is Bora라는 하나의 게시글에 댓글을 여러 번 쓴 것뿐인데, 마치 다른 글에 있는 댓글 같이 출력된다는 점이 문제이다. 물론, 큰 문제는 아니라고 여겨지지만, 가독성을 떨어뜨리는 요소임은 분명하다.
첫번째 버전에 비해 코드가 많이 복잡할 수 있다.
① Map
② for-each문
여기서 GetCommentRes와 getCommentRes는 완전히 다른 것이다. GetCommentRes는 게시글 제목과, 댓글 내용을 포함하는 자료형이고, getCommentRes는 GetCommentRes형 자료들을 모아둔 List의 이름이다. 보통 List의 이름을 변수명 뒤에 -s를 붙여 네이밍하는 것이 관례인데, getCommentRes에 뒤에 -s를 붙일 수 없어 다소 혼란이 야기될 수 있는 이름이 되어버린 것이다.
이제 API 테스트의 결과가 어떻게 바뀌는지 살펴보자. 이번에는 Chrome이 1번 게시글에 댓글을 3번이나 달고, 2,3번 게시글에 한번씩 댓글을 달았다.
postman에서 실행한 결과는 아래와 같다.
보다시피, 하나의 게시글에 달린 댓글끼리 잘 그룹화되어 결과가 출력된다. API 연습을 더 해보고 싶다면, 댓글을 삭제 및 수정하는 API도 작성해보기 바란다. 이에 대한 코드는 제공되지 않을 예정이지만, 충분히 할 수 있을 것이다.