
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();
}
포스트맨으로 테스트 해보자! (+테스트 코드도 돌려보면 좋겠죠?)


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는 줘야함
}

board가 null 이니까 2번 요청하면 이렇게 status가 404가 뜸 (내가 입력한 것)
근데 위에를 보면 200이 뜸. (서버가 통신 받은 것)
이러면 안된다.. 404가 떠야 fail로 들어간다! 일단 강제로 고쳐주자!

response.setStatus(404); 코드 넣어주자!
delete는 select가 아니니까 받아올 데이터가 없다!! 그러니 null을 return

잘 됨! 이제 fail을 타겠지!
4. index.mustache에 del함수 추가하기

이 index.mustache를 타는 ajax는 무조건 실행되어야 하니까 바깥에

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 자동으로 해주기) ]

[ 화면 확인 ]

postman으로 8번 게시글을 삭제하자 alert창 정상 작동

확인 버튼을 누르자 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