AJAX 통신 요청으로 삭제하기

coding S's avatar
Apr 19, 2024
AJAX 통신 요청으로 삭제하기

AJAX를 하니까 이제 @DeleteMapping 사용 가능!

→ 권한 체크는 생략하고 지금은 핵심 로직만 짜겠다
 

1. BoardApiController에서 @DeleteMapping("api/boards/{id}") 만들기

@RequiredArgsConstructor @RestController public class BoardApiController { private final BoardRepository boardRepository; // 삭제하기 @DeleteMapping("/api/boards/{id}") public ApiUtil<?> deleteById(@PathVariable Integer id) { boardRepository.deleteById(id); return new ApiUtil<>(null); //삭제는 데이터를 줄 게 없어서 null. 그래도 msg와 status는 줘야함 } // 주소 만들기 @GetMapping("api/boards") // 보드 줘라는 주소, 복수는 보드들 줘, 보드들 중에 1번 줘해서 복수형을 씀 public ApiUtil<List<Board>> findAll(HttpServletResponse response) { //response.setStatus(401); List<Board> boardList = boardRepository.selectAll(); // 상태코드랑 메세지랑 같이 줘야함 return new ApiUtil<>(boardList); // MessageConverter라는 클래스가 오브젝트를 응답할때 자동 발동함 } }
아이디 중복체크는 무조건 ajax로 해야 함! 아니면 적은 글이 다 날아가고, 로직이 실행이 안됨 * res에 html을 담아준다는 것은 말이 안됨 → index를 리턴하면 망함
 

2. BoardRepository에 deleteById() 만들기

@Transactional public void deleteById(Integer id) { Query query = em.createNativeQuery("delete from board_tb where id = ?"); query.setParameter(1, id); query.executeUpdate(); }
💡
포스트맨으로 테스트 해보자! (+테스트 코드도 돌려보면 좋겠죠?)
notion image
notion image
 
8번 게시글을 제이쿼리로 찾아서 remove 해주면 끝! -> CSR 하려고!! SSR은 F5를 해줘야함 ㅠㅠ 통신을 또 해야함...
 

3. BoardApiController에 api/boards/{id}에 null일 때 셋팅하기

@RequiredArgsConstructor @RestController public class BoardApiController { private final BoardRepository boardRepository; @DeleteMapping("/api/boards/{id}") public ApiUtil<?> deleteById(@PathVariable Integer id) { Board board = boardRepository.selectOne(id); if (board == null) { return new ApiUtil<>(404, "해당 게시글을 찾을 수 없습니다"); } boardRepository.deleteById(id); return new ApiUtil<>(null); //삭제는 데이터를 줄 게 없어서 null. 그래도 msg와 status는 줘야함 }
notion image
board가 null 이니까 2번 요청하면 이렇게 status가 404가 뜸 (내가 입력한 것) 근데 위에를 보면 200이 뜸. (서버가 통신 받은 것) 이러면 안된다.. 404가 떠야 fail로 들어간다! 일단 강제로 고쳐주자!
notion image
response.setStatus(404); 코드 넣어주자!
💡
delete는 select가 아니니까 받아올 데이터가 없다!! 그러니 null을 return
notion image
잘 됨! 이제 fail을 타겠지!
 

4. index.mustache에 del함수 추가하기

notion image
💡
이 index.mustache를 타는 ajax는 무조건 실행되어야 하니까 바깥에
notion image
💡
del의 ajax는 이벤트가 발생할 때 실행되어야 하니까 function 안에 넣어주기!
근데 이러면 DB에는 데이터가 사라졌는데 화면에는 게시글 8번이 남아있다. f5를 누르기 전까진 계속... 화면에 8번 게시글이 남아있다. 클라이언트는 영문도 모르고 있는데 왜 삭제된 게시글이래? 하면서 계속 누르겠지... 이렇게 그대로 있으면 f5를 누르기 전까지 클라이언트는 왜 안되는지 영문을 모를테니 고치자!

index.mustache 전체 코드

<script> function del(boardId) { $.ajax({ url: `/api/boards/${boardId}`, type: "delete" }).done((res) => { $(`#board-${boardId}`).remove(); }).fail((res) => { alert(res.responseJSON.msg); location.reload(); //f5 해주기 }); } $.ajax({ url: "/api/boards", type: "get" }).done((res) => { console.log("통신 성공"); console.log(res); // 통신 성공했을 때 body 값을 받아서 for문 돌릴 것 // for(board of boardList) { 라는 for문 돌려도 됨 let boardList = res.body; boardList.forEach((board)=>{ $("#board-box").append(render(board)); }); }).fail((res) => { // console.log("통신 실패"); // console.log(res); alert(res.responseJSON.msg); //location.href = "/loginForm"; });
 

[ 좋은 ux를 주려면 - location.reload(); (f5 자동으로 해주기) ]

notion image
 

[ 화면 확인 ]

notion image
postman으로 8번 게시글을 삭제하자 alert창 정상 작동
notion image
확인 버튼을 누르자 location.reload(); 덕분에 자동으로 f5가 되어서 8번 게시글이 사라진 창을 '클라이언트 사이드 랜더링' 해서 보여준다. 딱 삭제된 저 게시글 부분만 CSR 되는 것!!
 

[ 푸시 서버(push server) ] → 메시지나 알림을 실시간으로 전송하기 위한 서버

주로 모바일 애플리케이션에서 사용되며, 사용자에게 새로운 메시지, 업데이트, 이벤트, 푸시 알림 등을 실시간으로 알려줄 때 활용된다. 이를 통해 애플리케이션 사용자들은 중요한 정보를 놓치지 않고 즉시 받아볼 수 있다. 서버에 대한 요청 없이도 서버에서 메시지를 받을 수 있게 해줌
 

[ delete 전체 코드 ]

[ ApiUtil ]

package shop.mtcoding.blog.board; import lombok.AllArgsConstructor; import lombok.Data; @AllArgsConstructor @Data public class ApiUtil<T> { private Integer status; // 200, 400, 404, 405 private String msg; //성공, 실패시 -> 정확한 메세지 private T body; //바디 데이터는 타입이 여러가지니까 //일단 지금은 고정 값으로 적어주자 public ApiUtil(T body) { this.status = 200; this.msg = "성공"; this.body = body; } public ApiUtil(Integer status, String msg) { this.status = status; this.msg = msg; this.body = null; } }

[ BoardApiController ]

@DeleteMapping("/api/boards/{id}") public ApiUtil<?> deleteById(@PathVariable Integer id, HttpServletResponse response) { Board board = boardRepository.selectOne(id); if (board == null) { response.setStatus(404); return new ApiUtil<>(404, "해당 게시글을 찾을 수 없습니다"); } boardRepository.deleteById(id); return new ApiUtil<>(null); //삭제는 데이터를 줄 게 없어서 null. 그래도 msg와 status는 줘야함 }

[ index.mustache ]

<script> function del(boardId) { $.ajax({ url: `/api/boards/${boardId}`, type: "delete" }).done((res) => { $(`#board-${boardId}`).remove(); }).fail((res) => { alert(res.responseJSON.msg); location.reload(); //f5 해주기 }); }

[ BoardRepository ]

@Transactional public void deleteById(Integer id) { Query query = em.createNativeQuery("delete from board_tb where id = ?"); query.setParameter(1, id); query.executeUpdate(); }
 
Share article

codingb