메타코딩 SNS프로젝트

55. chapter 10. 댓글 - Comment API 생성하기, Ajax 작성하기 (컨트롤러, 서비스 만들기), 댓글쓰기 Ajax 함수 만들기

정현3 2022. 7. 9. 14:51

'모델링'이 완료되었으니 당연히 Controller와 Service도 같이 만들어주어야 한다.

우선 Service의 틀을 만들어준다.

package com.cos.photogramstart.service;

import com.cos.photogramstart.domain.comment.Comment;
import com.cos.photogramstart.domain.comment.CommentRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Service
public class CommentService {

    private final CommentRepository commentRepository;

    @Transactional
    public Comment 댓글쓰기() {

        return null;
    }

    @Transactional
    public void 댓글삭제() {

    }
}

이후 API Controller를 만들어주자.

package com.cos.photogramstart.web.api;


import com.cos.photogramstart.service.CommentService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RestController
public class CommentApiController {

    private final CommentService commentService;

    @PostMapping("api/comment")
    public ResponseEntity<?> commentSave() {

        commentService.댓글쓰기();

    }

    @DeleteMapping("/api/comment/{id}")
    public ResponseEntity<?> commentDelete(@PathVariable int id) {

        commentService.댓글삭제(id);
    }
}

댓글이 View에 뿌려질 자리는 story.js에 있다.

       <div id="storyCommentList-${image.id}">

         <div class="sl__item__contents__comment" id="storyCommentItem-1"">
               <p>
                  <b>Lovely :</b> 부럽습니다.
               </p>

               <button>
                  <i class="fas fa-times"></i>
               </button>

            </div>

         </div>

         <div class="sl__item__input">
            <input type="text" placeholder="댓글 달기..." id="storyCommentInput-${image.id}" />
            <button type="button" onClick="addComment(${image.id})">게시</button>
   </div>

</div>

댓글을 입력해보면 계속 '고정된 값'이 나오고 있다.

 

우선 '변수 바인딩'부터 해주자.

       <div class="sl__item__input">
         <input type="text" placeholder="댓글 달기..." id="storyCommentInput-${image.id}" />
         <button type="button" onClick="addComment(${image.id})">게시</button>
</div>

누가 썼는지에 대한 정보는 날리지 않아도 이미 가지고 있다.

이제 addComment() 메서드에서 Ajax를 작성해보자.

 

당연하게도 imageId를 받아주어야 한다.

// (4) 댓글쓰기
function addComment(imageId) {

   let commentInput = $(`#storyCommentInput-${imageId}`);
   let commentList = $(`#storyCommentList-${imageId}`);

-> 다음 코드를 보면 storyCommentList-1번을 찾아서 뿌리게 되는데 이것도 '변수 바인딩'을 해주도록 하자. 

당연히 댓글은 image에 담기므로 imageId를 담아주어야 한다.

<div id="storyCommentList-${image.id}">

   <div class="sl__item__contents__comment" id="storyCommentItem-1"">
         <p>
            <b>Lovely :</b> 부럽습니다.
         </p>

         <button>
            <i class="fas fa-times"></i>
         </button>

      </div>

   </div>

잘 찾아지는지 확인해보자.

List는 성공적으로 '변수 바인딩'이 되었다.

실제 댓글인 storyCommentItem은 DB에 담긴 데이터를 받아서 뿌려줄 것이다.

 

addComment()를 보면 해당 image를 받아와서 '댓글정보'를 data.content에 담고 해당 데이터가 null이라면 "댓글을 작성해주세요!"라는 메세지를 알림띄우도록 되어있다.

그리고 내용이 있다면 '샘플데이터'가 prepend로 담겨서 응답되도록 되어있다.

append는 작성한 순서대로, prepend는 최신 순서대로 뿌려주는 방식이다.

 

우선 이미지를 찾을 수 있게 imageId를 다 걸어주자.

data에 담을 때 content만 담을게 아니라, imageId도 담아야 한다.

user정보는 session을 이용하면 되기 때문에 별도로 담지 않아도 된다.


// (4) 댓글쓰기
function addComment(imageId) {

   let commentInput = $(`#storyCommentInput-${imageId}`);
   let commentList = $(`#storyCommentList-${imageId}`);

   let data = {
      imageId:imageId,
      content: commentInput.val()
   }

   //console.log(data);
   //console.log(JSON.stringify(data));


   if (data.content === "") {
      alert("댓글을 작성해주세요!");
      return;
   }

   $.ajax({

      type:"post",
      url:"/api/comment",
      data: JSON.stringify(data),
      contentType:"application/json;charset=utf-8",
      dataType:"json"
   }).done(res=> {

      console.log("댓글쓰기 성공",res)
   }).fail(error=>{
      console.log("댓글쓰기 실패", error)
   });

-> '샘플 데이터'가 content에 담기기 전에 AJAX 통신을 통해서 데이터를 변경해야 한다.

해당 데이터는 '자바스크립트'의 형태이기 때문에, contentType을 json이라고 알려주어야 한다.

-> 이제 /api/comment로 POST 요청을 하게 될텐데, image와 content를 받고 있다.

이 데이터를 담을 DTO를 만들어 주어야 한다.