drf-spectacular icon indicating copy to clipboard operation
drf-spectacular copied to clipboard

Relax "only unsafe methods can have a requestBody" constraint

Open glennmatthews opened this issue 1 year ago • 3 comments

Describe the bug

drf_spectacular.openapi.AutoSchema asserts that "only unsafe methods can have a body" and therefore will not render a requestBody for a DELETE endpoint, even if the view function is decorated with @extend_schema(request=...). While I'm aware that the relevant standards discourage including a requestBody in a DELETE, there are nevertheless existing APIs that do expect such. The OpenAPI 3.1 spec also permits (but discourages) this pattern:

In other cases where the HTTP spec is vague (such as GET, HEAD and DELETE), requestBody is permitted but does not have well-defined semantics and SHOULD be avoided if possible.

It would be useful for drf-spectacular to relax this constraint so as to allow more accurately documenting such non-standard REST APIs.

At present I've worked around this in an AutoSchema subclass by overriding get_operation() to explicitly re-add the requestBody back to the appropriate set of DELETE endpoints, but it would be nice to not have to do so. (Another more targeted approach would be to directly override _get_request_body() to remove this check but I hate to override private methods).

To Reproduce

Decorate a delete endpoint with @extend_schema(request=...) and observe that the generated schema still reports no requestBody for this endpoint.

Expected behavior

Appropriately-decorated DELETE endpoints should be represented in the generated schema with an appropriately constructed requestBody.

glennmatthews avatar Sep 14 '22 20:09 glennmatthews

Hi Glenn,

I get your point. This has been raised a couple of times. See here for my previous comment https://github.com/tfranzel/drf-spectacular/issues/431#issuecomment-862738643

The request body applicable for this operation. The requestBody is only supported in HTTP methods where the HTTP 1.1 specification [RFC7231] has explicitly defined semantics for request bodies. In other cases where the HTTP spec is vague, requestBody SHALL be ignored by consumers.

From https://spec.openapis.org/oas/v3.0.3#operation-object

The request body applicable for this operation. The requestBody is fully supported in HTTP methods where the HTTP 1.1 specification [RFC7231] has explicitly defined semantics for request bodies. In other cases where the HTTP spec is vague (such as GET, HEAD and DELETE), requestBody is permitted but does not have well-defined semantics and SHOULD be avoided if possible.

From https://spec.openapis.org/oas/v3.1.0#operation-object

So you could say this was relaxed a bit, but still strongly discouraged. At the moment we only support 3.0.3 though. And if I remember correctly, the schema validation failed with the official OpenAPI jsonschema specification

My stance was that we will not support this officially as long as it violates the spec. This could of course be lifted once we move to 3.1 and it passes, but I have not checked this detail with the 3.1 jsonschema specification yet.

tfranzel avatar Sep 14 '22 22:09 tfranzel

Thanks for the reply! Not sure how I missed finding #431 before. Feel free to close this as a duplicate if you like. :-)

I will point to the discussion on https://github.com/OAI/OpenAPI-Specification/pull/1937 - it was originally going to be permitted in v3.0.3 but the point was raised that that might be a SemVer violation, so it was backed out and changed only in 3.1.0 instead.

glennmatthews avatar Sep 15 '22 12:09 glennmatthews

Sure! I'll leave this open as a reminder for 3.1 support.

tfranzel avatar Sep 15 '22 13:09 tfranzel