[http] 엔티티 본문이 HTTP DELETE 요청에 허용됩니까?

HTTP DELETE 요청을 발행 할 때 요청 URI는 삭제할 자원을 완전히 식별해야합니다. 그러나 요청의 엔터티 본문의 일부로 추가 메타 데이터를 추가 할 수 있습니까?



답변

사양 은 명시 적으로 금지하거나 권장하지 않으므로 허용된다고 말하는 경향이 있습니다.

Microsoft는 동일한 방식으로 (청중의 불평 소리를들을 수 있음) MSDN 문서 에서 AELE.NET Data Services FrameworkDELETE 방법에 대해 설명합니다 .

삭제 요청에 엔티티 본문이 포함 된 경우 본문은 무시됩니다. […]

또한 요청과 관련하여 RFC2616 (HTTP 1.1)의 내용은 다음과 같습니다.

  • 엔티티 본체 때만 존재 메시지 본문은 본 인 (7.2)
  • 메시지 본문 의 존재는 Content-Length또는 Transfer-Encoding헤더를 포함함으로써 알린다 (4.3 절)
  • 메시지 본문이 요청 방법의 지정은 송신을 허용하지 않을 경우 포함되지 않아야 엔티티 본체 (섹션 4.3)
  • 엔티티 바디가 명시 적으로 금지되어 TRACE 만, 다른 모든 요청의 유형 (제 9, 특히 9.8)를 제한없는되는 요청

응답을 위해 다음과 같이 정의되었습니다.

  • 되든지 관계없이 메시지 본문을 포함하는 두 요청 방법에 의존 하고 응답 상태 (4.3 절)
  • 메시지 본문을 명시 적으로 (특히 제 9, 9.4) HEAD 요청에 대한 응답으로 금지
  • 메시지 본문을 명시 1XX (정보) (204) (내용이없는)에서 금지하고 (304) (개질되지 않음) 응답 (섹션 4.3)되고
  • 길이가 0 일 수 있지만 다른 모든 응답에는 메시지 본문이 포함됩니다 (4.3 절).

답변

HTTP 1.1 스펙 ( RFC 7231 )에 대한 최신 업데이트 는 DELETE 요청에서 엔티티 본문을 명시 적으로 허용합니다.

DELETE 요청 메시지 내의 페이로드에는 정의 된 의미가 없습니다. DELETE 요청에서 페이로드 본문을 전송하면 일부 기존 구현에서 요청을 거부 할 수 있습니다.


답변

Tomcat 및 Jetty의 일부 버전은 엔티티 본문이있는 경우 엔티티 본문을 무시하는 것 같습니다. 당신이 그것을 받으려는 경우 성가신 일이 될 수 있습니다.


답변

삭제 요청에서 본문을 사용하는 한 가지 이유는 낙관적 동시성 제어입니다.

레코드 버전 1을 읽습니다.

GET /some-resource/1
200 OK { id:1, status:"unimportant", version:1 }

동료가 레코드 버전 1을 읽습니다.

GET /some-resource/1
200 OK { id:1, status:"unimportant", version:1 }

동료가 레코드를 변경하고 데이터베이스를 업데이트하여 버전을 2로 업데이트합니다.

PUT /some-resource/1 { id:1, status:"important", version:1 }
200 OK { id:1, status:"important", version:2 }

레코드를 삭제하려고합니다.

DELETE /some-resource/1 { id:1, version:1 }
409 Conflict

낙관적 잠금 예외가 발생합니다. 레코드를 다시 읽고 중요한지 확인하고 삭제하지 마십시오.

이를 사용하는 또 다른 이유는 한 번에 여러 레코드를 삭제하는 것입니다 (예 : 행 선택 확인란이있는 그리드).

DELETE /messages
[{id:1, version:2},
{id:99, version:3}]
204 No Content

각 메시지에는 고유 한 버전이 있습니다. 여러 헤더를 사용하여 여러 버전을 지정할 수도 있지만 George가 더 간단하고 편리합니다.

이것은 Tomcat (7.0.52) 및 Spring MVC (4.05)에서 작동하며 이전 버전에서도 가능합니다.

@RestController
public class TestController {

    @RequestMapping(value="/echo-delete", method = RequestMethod.DELETE)
    SomeBean echoDelete(@RequestBody SomeBean someBean) {
        return someBean;
    }
}


답변

RFC 2616 이 이것을 지정하지 않은 것으로 보입니다 .

섹션 4.3에서 :

요청에 메시지 본문이 존재한다는 것은 요청의 메시지 헤더에 Content-Length 또는 Transfer-Encoding 헤더 필드를 포함시킴으로써 알 수 있습니다. 요청 방법 (5.1.1 절)의 명세가 엔티티 본문을 요청으로 전송하는 것을 허용하지 않는다면, 메시지 본문은 요청에 포함되어서는 안된다 (MUST NOT). 서버는 요청시 메시지 본문을 읽고 전달해야합니다. 요청 방법에 엔티티 본문에 대해 정의 된 의미가 포함되어 있지 않으면 요청을 처리 할 때 메시지 본문을 무시해야합니다.

섹션 9.7 :

DELETE 메소드는 오리진 서버가 Request-URI로 식별 된 자원을 삭제하도록 요청합니다. 이 방법은 오리진 서버에서 사람의 개입 (또는 다른 수단)에 의해 무시 될 수 있습니다. 오리진 서버에서 리턴 된 상태 코드가 조치가 완료되었음을 표시하더라도 클라이언트는 조작이 수행되었음을 보증 할 수 없습니다. 그러나 서버는 응답이 제공 될 때 리소스를 삭제하거나 액세스 할 수없는 위치로 이동시키지 않는 한 성공을 나타내서는 안됩니다.

응답에 상태를 설명하는 엔터티가 포함 된 경우 성공적인 응답은 200 (OK)이고, 조치가 아직 시행되지 않은 경우 202 (Accepted), 조치가 시행되었지만 응답이 포함되지 않은 경우 204 (No Content) 여야합니다. 실체.

요청이 캐시를 통과하고 Request-URI가 현재 캐시 된 하나 이상의 엔티티를 식별하는 경우 해당 항목은 오래된 것으로 취급해야합니다. 이 방법에 대한 응답은 캐시 할 수 없습니다 .c

따라서 명시 적으로 허용되거나 허용되지 않으며, 진행중인 프록시가 메시지 본문을 제거 할 가능성이 있습니다 (읽고 전달해야하지만).


답변

DELETE 요청에 본문을 제공하고 Google 클라우드 HTTPS로드 밸런서를 사용하는 경우 400 오류로 요청이 거부됩니다. 나는 벽에 머리를 대고 있었고, 구글은 어떤 이유로 든 몸에 대한 삭제 요청이 잘못된 요청이라고 생각했다.


답변

버전 3.0에 대한 OpenAPI 사양은 본문과 함께 DELETE 메소드에 대한 지원을 중단했음을 주목할 가치가 있습니다.

참조 여기여기에 참조를

이는 향후 구현, 문서화 또는 이러한 API 사용에 영향을 줄 수 있습니다.