[http] DELETE 요청 본문에 대한 RESTful 대안

그동안 HTTP 1.1 사양이 보인다 에 메시지 본문 DELETE 요청을,에 대한 정의 의미가 없기 때문에 서버가 그것을 무시해야 함을 표시 것으로 보인다.

4.3 메시지 본문

서버는 모든 요청에 ​​대해 메시지 본문을 읽고 전달해야합니다. 요청 메소드가 엔티티 본문에 대해 정의 된 의미를 포함하지 않는 경우 요청을 처리 할 때 메시지 본문을 무시해야합니다 (SHOULD).

나는 이미 다음과 같은이 주제에 대한 몇 가지 관련 토론을 검토했습니다.

대부분의 토론은 DELETE에 메시지 본문을 제공하는 것이 허용 있다는 데 동의하는 것처럼 보이지만 일반적으로 권장되지 않습니다.

또한 DELETE에서 요청 본문을 지원하기 위해 이러한 라이브러리에 대해 점점 더 많은 개선 사항이 기록되는 것처럼 보이는 다양한 HTTP 클라이언트 라이브러리의 추세를 확인했습니다. 대부분의 도서관은 의무가있는 것처럼 보이지만 때로는 약간의 초기 저항이 있습니다.

내 사용 사례에서는 DELETE에 필요한 메타 데이터를 추가해야합니다 (예 : 삭제에 필요한 다른 메타 데이터와 함께 삭제 “이유”). 다음 옵션을 고려했지만 HTTP 사양 및 / 또는 REST 모범 사례와 완전히 적절하고 인라인 된 것은 없습니다.

  • 메시지 본문 -사양은 DELETE의 메시지 본문에 의미 값이 없음을 나타냅니다. HTTP 클라이언트에서 완전히 지원되지 않습니다. 표준 관행이 아님
  • 사용자 지정 HTTP 헤더 -사용자 지정 헤더를 요구하는 것은 일반적으로 표준 관행에 위배됩니다 . 그것들을 사용하는 것은 내 API의 나머지 부분과 일치하지 않으며 사용자 지정 헤더가 필요하지 않습니다. 또한 잘못된 사용자 정의 헤더 값을 나타내는 데 사용할 수있는 좋은 HTTP 응답이 없습니다 (아마도 별도의 질문 일 것입니다).
  • 표준 HTTP 헤더 -적절한 표준 헤더 없음
  • 쿼리 매개 변수쿼리 매개 변수를 추가하면 실제로 삭제되는 요청 URI가 변경됩니다. 표준 관행에 반하여
  • POST 방법 -(예 POST /resourceToDelete { deletemetadata }) POST는 삭제를위한 의미 론적 옵션이 아닙니다. POST는 실제로 원하는 반대 동작을 나타냅니다 (예 : POST는 리소스 부하를 생성하지만 리소스를 삭제해야 함).
  • 다중 메소드 -DELETE 요청을 두 개의 작업으로 분할 (예 : PUT 삭제 메타 데이터, 다음 DELETE)하면 원자 적 작업이 두 개로 분할되어 잠재적으로 일관성없는 상태가 남습니다. 삭제 이유 (및 기타 관련 메타 데이터)는 리소스 표현 자체의 일부가 아닙니다.

내 첫 번째 선호도는 아마도 사용자 정의 HTTP 헤더에 이어 메시지 본문을 사용하는 것입니다. 그러나 표시된대로 이러한 접근 방식에는 몇 가지 단점이 있습니다.

DELETE 요청에 필요한 메타 데이터를 포함하기위한 REST / HTTP 표준과 관련된 권장 사항 또는 모범 사례가 있습니까? 고려하지 않은 다른 대안이 있습니까?



답변

DELETE 요청에 메시지 본문을 사용하지 말라는 몇 가지 권장 사항에도 불구하고이 접근 방식은 특정 사용 사례에 적합 할 수 있습니다. 이것은 우리가 질문 / 답변에 언급 된 다른 옵션을 평가하고 서비스 소비자와 협력 한 후에 사용한 접근 방식입니다.

메시지 본문의 사용이 이상적이지는 않지만 다른 옵션 중 어느 것도 완벽하게 적합하지 않았습니다. 요청 본문 DELETE를 사용하면 DELETE 작업을 수반하는 데 필요한 추가 데이터 / 메타 데이터에 대한 의미 체계를 쉽고 명확하게 추가 할 수 있습니다.

나는 여전히 다른 생각과 토론에 열려 있지만이 질문에 대한 루프를 닫고 싶었습니다. 이 주제에 대한 모든 사람의 생각과 토론에 감사드립니다!


답변

당신이 원하는 것은 두 가지 중 하나입니다 DELETE.

  1. 두 가지 작업이 있습니다 . PUT하나는 삭제 이유이고 그 뒤에는 DELETE하나의 리소스가 있습니다. 삭제 된 리소스의 내용은 더 이상 누구에게도 액세스 할 수 없습니다. ‘이유’에는 삭제 된 리소스에 대한 하이퍼 링크가 포함될 수 없습니다. 또는,
  2. 당신은 자원 변경하려는 에서 state=active로를 state=deleted사용하여 DELETE방법을. state = deleted 인 리소스는 기본 API에서 무시되지만 관리자 또는 데이터베이스 액세스 권한이있는 사람은 여전히 ​​읽을 수 있습니다. 이는 허용됩니다 DELETE. 리소스에 대한 백업 데이터를 지울 필요가 없으며 해당 URI에 노출 된 리소스 만 제거 할 수 있습니다.

메시지 본문이 필요한 모든 작업 DELETE요청POST 이 필요한 모든 작업은 가장 일반적으로, 메시지 본문으로 필요한 모든 작업을 수행하는 작업과 DELETE. HTTP의 의미를 깨뜨릴 이유가 없습니다.


답변

상황을 감안할 때 다음 접근 방식 중 하나를 사용합니다.

  • PUT 또는 PATCH 보내기 : 삭제 이유가 필요한 특성상 삭제 작업이 가상이라고 추론하고 있습니다. 따라서 PUT / PATCH 작업을 통해 레코드를 업데이트하는 것은 DELETE 작업 자체는 아니지만 유효한 방법이라고 생각합니다.
  • 쿼리 매개 변수 사용 : 리소스 URI가 변경되지 않습니다. 나는 이것이 또한 유효한 접근이라고 생각합니다. 연결 한 질문은 쿼리 매개 변수가 누락 된 경우 삭제를 허용하지 않는 것에 대한 것입니다. 귀하의 경우에는 이유가 쿼리 문자열에 지정되지 않은 경우 기본 이유가 있습니다. 리소스는 여전히 resource/:id. 각 이유에 대해 리소스의 링크 헤더를 사용하여 검색 가능하게 만들 수 있습니다 (각 이유 rel를 식별 하는 태그 포함).
  • 이유에 따라 별도의 엔드 포인트 사용 과 같은 URL을 사용을 : resource/:id/canceled. 이것은 실제로 Request-URI를 변경하며 확실히 RESTful이 아닙니다. 다시 말하지만, 링크 헤더는이를 검색 가능하게 만들 수 있습니다.

REST는 법이나 교리가 아님을 기억하십시오. 지침으로 더 생각하십시오. 따라서 문제 영역에 대한 지침을 따르지 않는 것이 합리적 일 때 그렇게하지 마십시오. API 소비자에게 차이를 알려주십시오.


답변

필요한 메타 데이터를 URI 계층 자체의 일부로 포함하는 것이 좋습니다. 예 (순진한) :

날짜 범위를 기준으로 항목을 삭제해야하는 경우 시작 날짜와 종료 날짜를 본문 또는 쿼리 매개 변수로 전달하는 대신 URI의 일부로 필요한 정보를 전달하는 방식으로 URI를 구성합니다.

예 :

DELETE /entries/range/01012012/31122012 -2012 년 1 월 1 일부터 2012 년 12 월 31 일 사이의 모든 항목 삭제

도움이 되었기를 바랍니다.


답변