1. लाइब्रेरी
  2. HTTP와 웹
  3. HTTP 메서드

अपडेट किया गया 1 माह पहले

DELETE는 서버에서 리소스를 제거합니다. 요청 자체는 단순합니다. 하지만 그 의미는 그렇지 않습니다.

요청

DELETE 요청은 최소한의 구성으로 이루어집니다. URL이 삭제할 대상을 지정하고, 헤더가 인증을 처리합니다. 본문은 일반적으로 없습니다.

DELETE /articles/12345 HTTP/1.1
Host: api.example.com
Authorization: Bearer token123

DELETE가 성공하면, 해당 URL로 GET 요청을 보냈을 때 404 Not Found가 반환되어야 합니다. 리소스가 사라진 것입니다.

응답

204 No Content는 가장 일반적인 성공 응답입니다—리소스가 삭제되었으며 더 이상 전달할 내용이 없습니다:

HTTP/1.1 204 No Content

200 OK는 삭제된 항목에 대한 정보를 반환하고 싶을 때 사용합니다:

{
  "id": 12345,
  "deleted_at": "2024-05-15T10:30:00Z"
}

202 Accepted는 삭제가 대기열에 추가되었지만 아직 완료되지 않았음을 나타냅니다—대용량 데이터를 제거할 때 유용합니다.

404 Not Found는 리소스가 존재하지 않는다는 의미입니다. 그런데 여기서 흥미로운 질문이 생깁니다.

409 Conflict는 리소스를 삭제할 수 없는 상태임을 나타냅니다—의존성이 있거나 비즈니스 규칙에 의해 삭제가 차단된 경우입니다.

멱등성의 역설

DELETE는 멱등적입니다: 여러 번 호출해도 한 번 호출한 것과 동일한 결과를 가져야 합니다. 하지만 무언가를 파괴하는 건 한 번밖에 할 수 없습니다. 이미 삭제된 리소스에 DELETE를 보내면 어떻게 될까요?

첫 번째 입장—404 반환: "리소스가 존재하지 않습니다. 없는 것을 삭제할 수는 없습니다."

DELETE /articles/12345
→ 첫 번째 요청: 204 No Content
→ 두 번째 요청: 404 Not Found

두 번째 입장—204 반환: "이 리소스가 존재하지 않도록 해달라고 요청하셨습니다. 완료했습니다."

DELETE /articles/12345
→ 첫 번째 요청: 204 No Content  
→ 두 번째 요청: 204 No Content

두 입장 모두 나름의 근거가 있습니다. 404 방식은 요청이 실제로 무언가를 변경했는지 알려줍니다. 204 방식은 최종 상태를 강조합니다—리소스가 사라졌으며, 그것이 원했던 결과입니다.

대부분의 현대 API는 404를 반환하지만, 이 논쟁은 실질적인 문제를 드러냅니다. 삭제는 행위("이것을 제거하라")인가요, 아니면 결과("이것이 없는 상태를 보장하라")인가요? HTTP 명세는 답을 주지 않습니다. 직접 결정해야 합니다.

소프트 삭제

많은 애플리케이션은 데이터를 실제로 삭제하지 않습니다. 삭제된 것으로 표시할 뿐입니다:

UPDATE articles SET deleted_at = NOW() WHERE id = 12345;

API 관점에서 보면 리소스는 사라진 것입니다—GET은 404를 반환하고, 목록에서도 보이지 않습니다. 하지만 데이터는 데이터베이스에 남아 있어 필요하면 복구할 수 있습니다.

이 방식은 다음을 제공합니다:

  • 실수로 인한 삭제에서의 복구
  • 무엇이 언제 삭제되었는지 보여주는 감사 추적
  • 데이터 보존을 요구하는 규정에 대한 규정 준수
  • 삭제된 항목을 참조하는 리소스의 참조 무결성

일부 API는 이를 명시적으로 노출하기도 합니다:

GET /articles?include_deleted=true
POST /articles/12345/restore

조건부 삭제

파괴에는 실행 취소 버튼이 없습니다. 조건부 요청은 그 선을 넘기 전에 안전을 확인하는 수단입니다.

If-Match 헤더는 삭제하려는 것이 정말 의도한 것인지 확인합니다:

DELETE /articles/12345 HTTP/1.1
If-Match: "etag-abc123"

마지막으로 읽은 이후 아티클이 수정되었다면—삭제를 결정하는 동안 다른 누군가가 편집했다면—ETag가 일치하지 않습니다:

HTTP/1.1 412 Precondition Failed

이렇게 하면 특정 종류의 비극을 방지할 수 있습니다: 한 번도 본 적 없는 변경 사항이 담긴 리소스를 삭제하는 일 말입니다.

일괄 삭제

여러 리소스를 한 번에 삭제하는 것은 강력하면서도 위험합니다. 여러 패턴이 존재합니다:

개별 요청: 단순하고 안전하지만, 호출이 잦습니다.

DELETE /articles/1
DELETE /articles/2
DELETE /articles/3

쿼리 파라미터: 강력하지만 위험합니다.

DELETE /articles?status=draft&created_before=2024-01-01

잘못 설정된 필터 하나로 모든 것이 삭제될 수 있습니다.

명시적 일괄 엔드포인트: RESTful하지는 않지만 안전합니다.

POST /articles/bulk-delete
{"ids": [1, 2, 3, 4, 5]}

일괄 작업에서는 우아함보다 명확함을 우선시하세요. 명시적으로 표현하는 것 자체가 기능입니다.

보안

DELETE는 신중한 보호가 필요합니다:

인증: 익명 삭제를 절대 허용하지 마세요.

권한 부여: 사용자가 해당 특정 리소스를 삭제할 수 있는지 확인하세요. 하나의 리소스를 소유한다고 해서 모든 리소스를 소유하는 것은 아닙니다.

CSRF 보호: 악성 사이트가 브라우저를 속여 DELETE 요청을 보내지 못하도록 방지하세요.

속도 제한: 무제한 DELETE 접근 권한을 가진 탈취된 계정은 치명적입니다.

감사 로깅: 타임스탬프, 사용자, 삭제된 내용과 함께 모든 삭제를 기록하세요. 문제가 생겼을 때 이 기록이 필요합니다.

연쇄 동작: 의존 리소스에 무슨 일이 일어날지 결정하세요. 함께 삭제할까요? 오류를 반환할까요? 그 답이 데이터 무결성에 영향을 미칩니다.

비동기 삭제

대용량 데이터를 삭제하는 데는 시간이 걸립니다. 클라이언트를 기다리게 하는 대신, 요청을 확인하고 백그라운드에서 처리하세요:

DELETE /users/12345 HTTP/1.1
→
HTTP/1.1 202 Accepted
{
  "status": "pending",
  "job_id": "delete-job-789",
  "status_url": "/jobs/delete-job-789"
}

클라이언트는 작업이 완료될 때까지 상태 URL을 폴링합니다. 이 패턴은 합리적인 요청 타임아웃보다 더 오래 걸리는 모든 작업에 적용할 수 있습니다.

휴지통 패턴

사용자 대면 애플리케이션은 종종 소프트 삭제와 유예 기간을 결합합니다:

  1. DELETE 요청이 소프트 삭제를 트리거합니다
  2. 사용자에게는 리소스가 "삭제된" 것으로 표시됩니다
  3. 복구를 위한 30일 유예 기간이 주어집니다
  4. 유예 기간 이후 백그라운드 작업이 영구 삭제를 수행합니다

사용자는 즉각적인 삭제의 만족감을 얻습니다. 운영팀은 실수를 수정할 시간을 확보합니다.

HTTP DELETE 메서드에 관한 자주 묻는 질문

이미 삭제된 리소스에 대해 DELETE는 404와 204 중 무엇을 반환해야 하나요?

대부분의 API는 404를 반환합니다—요청이 실제로 무언가를 변경했는지 알 수 있기 때문입니다. 하지만 DELETE를 "이 리소스를 제거하라"가 아닌 "이 리소스가 존재하지 않도록 보장하라"로 본다면 204도 정당합니다. 하나의 방식을 선택하고 일관성을 유지하세요.

DELETE 요청에 본문이 있을 수 있나요?

HTTP 명세가 이를 금지하지는 않지만, 많은 클라이언트와 프록시가 이를 제대로 처리하지 못합니다. 일괄 삭제를 위한 ID 목록처럼 DELETE와 함께 데이터를 보내야 한다면 POST 엔드포인트를 사용하세요. RESTful하지는 않지만 더 안정적입니다.

소프트 삭제와 하드 삭제는 언제 사용해야 하나요?

실수로 인한 삭제가 큰 비용을 초래하는 사용자 데이터에는 소프트 삭제를 사용하세요. 세션 토큰처럼 일시적인 데이터나 GDPR의 "삭제권"처럼 실제 삭제를 요구하는 규정이 있을 때는 하드 삭제를 사용하세요.

연쇄 삭제는 어떻게 처리해야 하나요?

세 가지 옵션이 있습니다: 의존 리소스를 자동으로 삭제하거나(편리하지만 예상치 못한 결과 초래), 의존성이 제거될 때까지 409 Conflict를 반환하거나(안전하지만 여러 번의 요청 필요), 의존 리소스를 고아 상태로 표시합니다(데이터는 보존되지만 정리가 필요합니다). 선택한 방식을 명확하게 문서화하세요.

क्या यह पृष्ठ सहायक था?

😔
🤨
😃