카카오테크캠퍼스 선물하기 API를 구현하면서 삭제 요청에 필요한 값을 어디에 담아야 할지 고민했다. 기능 자체는 단순했다. 특정 리소스를 삭제하는 API였다.
하지만 API를 설계하다 보니 DELETE 요청에 Body를 넣는 방식이 적절한지 다시 검토했다. 서버에서는 Body를 읽을 수 있지만, 클라이언트나 중간 프록시, 문서화 도구에서 DELETE Body를 어떻게 다룰지까지 생각하면 불명확한 부분이 있었다.
이 글은 DELETE 요청에서 Body 사용을 지양하고, 더 명확한 API 형태로 정리한 기록이다.
처음 생각한 방식
처음에는 삭제에 필요한 값을 Body에 넣는 방식을 생각했다.
DELETE /api/wishlist
Content-Type: application/json
{
"productId": 1
}
서버 입장에서는 처리할 수 있었다. JSON으로 값을 받으면 확장도 쉬워 보였다. 하지만 REST API를 사용하는 입장에서는 DELETE 요청의 Body가 직관적이지 않을 수 있었다.
특히 삭제 대상이 명확한 경우라면, Body보다 URI에 삭제 대상을 드러내는 편이 더 읽기 쉬웠다.
원인을 확인한 과정
두 번째로는 Query Parameter를 검토했다.
DELETE /api/wishlist?productId=1
이 방식도 사용할 수 있었다. 다만 삭제 대상이 리소스 식별자라면 Query Parameter보다 Path Variable이 더 명확하다고 봤다. Query Parameter는 필터나 옵션처럼 보이기 쉽고, 삭제 대상 자체를 표현하기에는 힘이 조금 약했다.
해결 방안
최종적으로는 삭제할 대상을 URI 경로에 명확히 드러내는 형태로 정리했다.
DELETE /api/wishlist/items/{productId}
이 방식은 요청을 보는 사람도 어떤 리소스를 삭제하는지 바로 알 수 있다. API 문서에서도 설명이 단순해지고, 클라이언트에서도 사용 방식이 명확해졌다.
중요한 것은 DELETE Body가 절대 불가능하다는 뜻이 아니었다. 다만 이 프로젝트의 요구사항에서는 삭제 대상이 명확했기 때문에, Body를 쓰는 것보다 URI에 표현하는 방식이 더 적절했다.
정리한 기준
API 설계에서 확인한 기준은 아래와 같았다.
- 삭제 대상이 리소스 식별자인가
- 요청만 보고 의도가 명확한가
- 클라이언트와 문서화 도구가 일관되게 다루기 쉬운가
- 나중에 API를 보는 사람이 의미를 명확히 이해할 수 있는가
단순히 서버에서 처리 가능하다는 이유만으로 선택하지 않으려고 했다. API는 서버 구현만의 문제가 아니라, 클라이언트와 함께 쓰는 계약이기 때문이다.
마무리
이번 경험을 통해 REST API 설계에서는 동작 여부보다 표현의 명확성이 중요하다는 점을 다시 확인했다.
DELETE 요청에 Body를 넣을 수 있는지보다, 이 API가 어떤 리소스를 삭제하는지 명확히 드러나는지가 더 중요했다. 그래서 삭제 대상이 분명한 경우에는 Path Variable로 표현하는 방식을 선택했다.