[데브코스] Spring Boot REST API 실습 (21강) – 글/댓글 삭제를 GET이 아닌 DELETE로 변경 + React에서 DELETE 호출 가능할까?

zuno·2025년 12월 25일

이번 강의(21강)는 기능 추가가 아니라 API 설계를 REST답게 수정하는 단계였다.
기존에는 개발 편의를 위해 삭제를 GET 요청으로 처리했지만,
이번 강의에서는 HTTP Method의 의미에 맞게 DELETE로 변경했다.

그리고 강의 말미에 자연스럽게 이런 질문이 떠올랐다.

❓ “그럼 React 같은 프론트에서 DELETE 요청은 호출할 수 있나?”

이 글에서는 그 질문까지 같이 정리한다.


1️⃣ 왜 삭제를 GET으로 하면 안 될까?

기존 삭제 방식은 이런 형태였다.

GET /api/v1/posts/{id}/delete
GET /api/v1/posts/{postId}/comments/{id}/delete

❌ 문제점 1: HTTP 의미가 깨진다

  • GET → 조회 (서버 상태 변경 ❌)
  • DELETE → 삭제 (서버 상태 변경 ⭕

GET으로 삭제하면 URL만 보고는

  • “조회인지”
  • “삭제인지”
    알 수가 없다.

❌ 문제점 2: 캐시 / 프리페치 위험

GET 요청은 브라우저, 프록시, 크롤러 등에 의해

  • 캐싱
  • 자동 호출
    될 수 있다.

👉 GET으로 삭제하면 의도치 않은 삭제 사고가 발생할 수 있다.


2️⃣ 글 삭제 API – DELETE로 변경

📌 변경 전

GET /api/v1/posts/{id}/delete

📌 변경 후

DELETE /api/v1/posts/{id}

📌 컨트롤러 코드

@DeleteMapping("/{id}")
@Transactional
public RsData<Void> delete(@PathVariable int id) {
    Post post = postService.findById(id).get();

    postService.delete(post);

    return new RsData<>(
            "200-1",
            "%d번 글이 삭제되었습니다.".formatted(id)
    );
}

✅ 포인트

  • URL에는 명사(posts) 만 남긴다
  • “삭제”라는 행위는 HTTP Method(DELETE) 로 표현한다

3️⃣ 댓글 삭제 API – DELETE로 변경

📌 변경 전

GET /api/v1/posts/{postId}/comments/{id}/delete

📌 변경 후

DELETE /api/v1/posts/{postId}/comments/{id}

📌 컨트롤러 코드

@DeleteMapping("/{id}")
@Transactional
public RsData<Void> delete(
        @PathVariable int postId,
        @PathVariable int id
) {
    Post post = postService.findById(postId).get();

    PostComment postComment = post.findCommentById(id).get();

    postService.deleteComment(post, postComment);

    return new RsData<>(
            "200-1",
            "%d번 댓글이 삭제되었습니다.".formatted(id)
    );
}

✅ 포인트

  • 댓글은 글에 종속된 리소스
  • URL 구조만 봐도 의미가 명확하다
posts/{postId}/comments/{id}

4️⃣ 여기서 드는 추가 질문

❓ React에서 DELETE 요청은 호출할 수 있을까?

결론부터 말하면:

된다. 완전 가능하다.


5️⃣ React에서 DELETE 요청 보내는 방법

✅ fetch 사용

fetch("http://localhost:8080/api/v1/posts/1", {
  method: "DELETE",
});

✅ axios 사용

axios.delete("http://localhost:8080/api/v1/posts/1");

둘 다 정상적으로 DELETE 요청이 나간다.


6️⃣ 그런데 왜 “DELETE는 안 된다”는 말이 나올까?

보통 아래 3가지가 섞여서 오해가 생긴다.


1️⃣ CORS 문제

프론트(3000) → 백엔드(8080) 요청 시
DELETE / POST / PUT 은 프리플라이트(OPTIONS) 요청이 발생한다.

백엔드에 CORS 설정이 없으면:

  • GET은 되는 것 같고
  • DELETE는 막히는 것처럼 보인다

👉 이건 DELETE가 안 되는 게 아니라
👉 CORS 설정이 없어서 막힌 것


2️⃣ CSRF 문제 (Spring Security 사용 시)

Spring Security 기본 설정에서는:

  • GET ❌ 검사
  • DELETE / POST / PUT ⭕ CSRF 검사

그래서 토큰 없으면 DELETE가 차단된다.

👉 이 경우도 DELETE가 안 되는 게 아니라 보안 설정 문제


3️⃣ HTML form 한계와의 혼동

HTML <form> 태그는

  • GET
  • POST
    만 지원한다.

이걸 보고

“DELETE는 브라우저에서 못 보낸다”
라고 오해하는 경우가 많다.

하지만 React는:

  • form이 아니라
  • fetch / axios로 진짜 HTTP 요청을 보낸다

👉 DELETE 사용 가능


7️⃣ 정리

  • 삭제는 GET이 아니라 DELETE가 맞다
  • REST API는
    • URL = 리소스(명사)
    • Method = 행위
  • React에서도 DELETE 요청은 문제없이 가능
  • “안 된다”는 말은 대부분
    👉 CORS / CSRF / form 오해에서 나온다

💡 한 줄 요약

REST API에서 삭제는 GET이 아니라 DELETE,
그리고 React에서도 DELETE 요청은 당연히 가능하다.

0개의 댓글