게시판 사이트에 핵심인 글 삭제 기능을 개발하기로 했다.

삭제 흐름

  1. 사용자가 삭제 버튼 클릭(작성자에게만 노출)
  2. onclick -> deletePost(id) 실행, fetchDELETE /posts/{id}로 http 요청 전송
  3. Controller는 요청을 받아 SessionUser. id를 Service 계층으로 전송
  4. Service 계층
    1. findByIdWithUser(postId)로 Post + User 를 fetch join으로 로딩
    2. 게시글이 없을 경우 PostNotFoundException
    3. 작성자 검증 실패 시 PostAccessDeniedException
    4. 통과하면 post 객체 삭제
  5. Controller에서 ResponseEntity 리턴 ( 2xx 응답 반환(바디 없음))
  6. JS가 res.ok를 확인해 window.location.assign('/') 로 홈 이동.

post-detail.html

 <!-- 삭제 버튼 (작성자만 보이게)-->
        <button th:if ="${session.user != null and session.user.id == post.userId}"
                type ="button" class="btn-delete"
                th:onclick="|deletePost(${post.postId})|">삭제</button>

post-detail.js

async function deletePost(id) {
    if (!confirm('정말 삭제하시겠습니까?')) return;

    const token  = document.querySelector('meta[name="_csrf"]')?.content;
    const header = document.querySelector('meta[name="_csrf_header"]')?.content || 'X-CSRF-TOKEN';

    const res = await fetch(`/posts/${id}`, {
        method: 'DELETE',
        headers: token ? { [header]: token, 'X-Requested-With': 'XMLHttpRequest' } : { 'X-Requested-With': 'XMLHttpRequest' }
    });

    if (res.ok) {
        window.location.assign('/');            // ← 여기서 직접 이동
    } else {
        alert('삭제에 실패했습니다.');
    }

  1. 사용자 확인 절차
  1. 삭제 요청 전송 (fetch API)
  1. 서버 응답 처리

PostsApiController.java