programing

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

nasanasas 2020. 10. 2. 22:30
반응형

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


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


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

Microsoft는 동일한 방식으로보고 있습니다 (청중의 불평을들을 수 있음). ADO.NET 데이터 서비스 프레임 워크DELETE 방법에 대한 MSDN 문서에서 다음과 같이 설명합니다 .

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

또한 요청과 관련하여 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는 이를 지정하지 않습니다.

From section 4.3:

The presence of a message-body in a request is signaled by the inclusion of a Content-Length or Transfer-Encoding header field in the request's message-headers. A message-body MUST NOT be included in a request if the specification of the request method (section 5.1.1) does not allow sending an entity-body in requests. A server SHOULD read and forward a message-body on any request; if the request method does not include defined semantics for an entity-body, then the message-body SHOULD be ignored when handling the request.

And section 9.7:

The DELETE method requests that the origin server delete the resource identified by the Request-URI. This method MAY be overridden by human intervention (or other means) on the origin server. The client cannot be guaranteed that the operation has been carried out, even if the status code returned from the origin server indicates that the action has been completed successfully. However, the server SHOULD NOT indicate success unless, at the time the response is given, it intends to delete the resource or move it to an inaccessible location.

A successful response SHOULD be 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if the action has not yet been enacted, or 204 (No Content) if the action has been enacted but the response does not include an entity.

If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those entries SHOULD be treated as stale. Responses to this method are not cacheable.c

So it's not explicitly allowed or disallowed, and there's a chance that a proxy along the way might remove the message body (although it SHOULD read and forward it).


Just a heads up, if you supply a body in your DELETE request and are using a google cloud HTTPS load balancer, it will reject your request with a 400 error. I was banging my head against a wall and came to found out that Google, for whatever reason, thinks a DELETE request with a body is a malformed request.


It seems ElasticSearch uses this: https://www.elastic.co/guide/en/elasticsearch/reference/5.x/search-request-scroll.html#_clear_scroll_api

Which means Netty support this.

Like mentionned in comments it may not be the case anymore


It is worth noting that the OpenAPI specification for version 3.0 dropped support for DELETE methods with a body:

see here and here for references

This may affect your implementation, documentation, or use of these APIs in the future.


This is not defined.

A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request.
https://tools.ietf.org/html/rfc7231#page-29


I don't think a good answer to this has been posted, although there's been lots of great comments on existing answers. I'll lift the gist of those comments into a new answer:

This paragraph from RFC7231 has been quoted a few times, which does sum it up.

A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request.

What I missed from the other answers was the implication. Yes it is allowed to include a body on DELETE requests, but it's semantically meaningless. What this really means is that issuing a DELETE request with a request body is semantically equivalent to not including a request body.

Including a request body should not have any effect on the request, so there is never a point in including it.

tl;dr: Techically a DELETE request with a request body is allowed, but it's never useful to do so.


In case anyone is running into this issue testing, No it is not universally supported.

I am currently testing with Sahi Pro and it is very apparent a http DELETE call strips any provided body data (a large list of id's to delete in bulk as per endpoint design).

I have been in contact with them several times as well as sent in three separate packages of scrips, images, logs for them to review and they still have not confirmed this. A failed patch, and a missed conference calls by their support later and I still haven't gotten a solid answer.

I am certain Sahi does not support this, and I would imagine many other tools follow suite.


Using DELETE with a Body is risky... I prefer this approach for List Operations over REST:

Regular Operations

GET /objects/ Gets all Objects

GET /object/ID Gets an Object with specified ID

POST /objects Adds a new Object

PUT /object/ID Adds an Object with specified ID, Updates an Object

DELETE /object/ID Deletes the object with specified ID

All Custom actions are POST

POST /objects/addList Adds a List or Array of Objects included in body

POST /objects/deleteList Deletes a List of Objects included in body

POST /objects/customQuery Creates a List based on custom query in body

If a client doesn't support your extended operations they can work in the regular way.


I was able to implement DELETE operation with a Request body. I used AWS Lambda and AWS API gateway and used Go language.


Might be the below GitHUb url will help you, to get the answer. Actually, Application Server like Tomcat, Weblogic denying the HTTP.DELETE call with request payload. So keeping these all things in mind, I have added example in github,please have a look into that

https://github.com/ashish720/spring-examples

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

반응형