Operation/Rest API

REST API - Bulk delete 설계하는 방법!

JaeHoney 2022. 3. 30. 22:08

Bulk delete

REST API에서 리소스의 id array를 사용해서 Bulk delete를 해야할 때 어떻게 하면 좋을까요?

 

저의 경우 DELETE /resources 로 요청을 보내고, Body에 { ids: [] } 형식의 데이터를 넣어주면 안되는지 생각했었습니다.

 

 

Data의 위치

 

그런데, DELETE에서 Body에 데이터를 담는 것이 바람직한 방법이 아니라고 합니다.

 

왜냐하면, 일반적으로 HTTP 메소드를 사용할 때 데이터 위치는 아래와 같습니다.

 

GET, DELETE => header에 데이터 포함
POST, PUT => body에 데이터 포함

 

그래서, 클라이언트나 라이브러리, 미들웨어 등에서 이를 지원하지 않는 경우도 있기 때문에 나중에 문제를 일으키기 쉽습니다.

 

방법 1

첫 번째 방법은 구분자를 사용해서 path로 데이터를 넘기는 방법입니다.

  • DELETE /resources/1;2;3;4
  • DELETE /resources/1+2+3+4
  • DELETE /resources/1,2,3,4

방법 2

두 번째 방법은 QueryString을 사용하는 방법입니다.

  • DELETE /resources?id=1&id=2&id=3&id=4

 

방법 3

세 번째 방법은 POST나 PUT을 사용하는 방법입니다. 

 

첫 번째, 두 번째 방법의 문제점은 길이의 제약이 있다는 점입니다. 브라우저마다 URL의 Maximum length가 다르지만 보통 2048자나 2083자입니다.

 

이는 문제가 생길 가능성이 있습니다. 예를 들어, 클라이언트가 해당 길이 이상의 Id array를 URL에 담고 보내려 하면 당연히 문제가 발생하겠죠.

 

그래서 POST나 PUT을 사용해서 Body를 사용할 수 있게 설계할 수 있습니다.

  • POST /resources/batch-delete 
  • POST /resources/deleteList

이 경우 Body를 { ids: [] } 형태로 전송할 수 있습니다.

 

방법 4

네 번째 방법은 그냥 DELETE에 Body를 사용하는 것입니다.

 

ElasticSearch의 RestAPI의 경우에는 지금도 일부는 GET과 DELETE에서 Body를 사용합니다.

 

하지만 이는 좋은 방법이 아닙니다.

 

RFC2616 (HTTP 1.1)은 이렇게 설명합니다.

  • Entity-Body 전송을 하지 않는 경우 Message-Body에 포함하지 말아라!

즉, "서버는 Entity 본문을 정의하지 않으므로, Message-Body를 무시하라" 라는 의미를 가집니다.

 

따라서 Entity id는 본문에 있어선 안되고, Entity Body가 아닌 것이 Message Body에 있어선 안됩니다.

 

  • Android 에서는 DELETE와 함께 본문을 전송할 수 없음
  • Tomcat, Weblogic은 Payload가 있는 DELETE 요청을 거부
  • OpenAPI 사양에서 본문이 있는 DELETE 요청 지원을 중단
  • Google Cloud HTTPS LoadBalancer가 상태 값 400을 반환하는 DELETE 요청을 거부
  • Sahi Pro는 DELETE 요청에 제공된 Body를 무시
  • 일부 버전의 Tomcat 및 Jetty는 엔터티 본문을 무시

 

다른 곳에서는 어떻게 할까?

1. 개인적으로 저는 REST API 표준이라고 하면 Github API가 떠오릅니다.

 

REST API의 Uniform interface도 만족하고 있고, path가 명사로 잘 명시되어서 확장 및 분리도 가능합니다.

 

아쉽게도 Github API에서는 자원 일괄 삭제를 할 때 Issue별 comment를 전체 삭제하거나, Repository별 Issue를 전체 삭제하는 경우는 있어도 Id array를 기준으로 선택적으로 삭제를 하는 경우가 없었습니다.

 

 

2. Google이 궁금해서 구글 블로그의 선택 삭제 기능을 사용했는데, Delete 요청을 여러개 보내더라구요!

 

그럴 수도 있는 것 같습니다.

 

 

3. naver 블로그에서 선택 삭제를 하는 경우에는 POST를 사용하고 Body에 id array를 담아서 사용합니다.

 

 

 


 

마무리

 

API 스펙이 원래 모호하고 정답이 없는 부분이라고 생각합니다.

 

개인적으로 REST API 스펙으로는 첫 번째로 소개해드렸던 DELETE /resources/1,2,3,4 방법이 가장 REST에 가깝다고 생각하구요.

 

비즈니스 로직, 타협점에 따라 POST 요청을 사용할 수도 있을 것 같습니다.

 

감사합니다.

 

 

Reference:

- https://stackoverflow.com/questions/299628/is-an-entity-body-allowed-for-an-http-delete-request

- https://peterdaugaardrasmussen.com/2020/11/14/rest-should-you-use-a-body-for-your-http-delete-requests/