quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.78k stars 2.68k forks source link

OpenAPI lose Request Body Description if '@RequestBody' comes after another annotation #43338

Closed RacmanT closed 1 month ago

RacmanT commented 1 month ago

Describe the bug

Hi everyone! 👋

I've encountered a strange issue related to the documentation generated by OpenAPI. If the @RequestBody annotation and its corresponding parameter are placed last in the endpoint method's parameters, the description for the RequestBody is not generated by OpenAPI (see example below). This issue seems to occur only with String parameters.

Expected behavior

{
    "/fruits/{fruitName}/description": {
        "put": {
            "tags": [
                "Fruit Resource"
            ],
            "parameters": [
                {
                    "name": "fruitName",
                    "in": "path",
                    "description": "The name of the fruit",
                    "required": true,
                    "schema": {
                        "type": "string"
                    }
                }
            ],
            "requestBody": {
                "description": "The new fruit description",  // <===== description is present
                "content": {
                    "text/plain": {
                        "schema": {
                            "type": "string"
                        }
                    }
                },
                "required": true
            },
            "responses": {
                "200": {
                    "description": "OK"
                }
            }
        }
    }
}

Actual behavior

{
    "/fruits/{fruitName}/description": {
        "put": {
            "tags": [
                "Fruit Resource"
            ],
            "parameters": [
                {
                    "name": "fruitName",
                    "in": "path",
                    "description": "The name of the fruit",
                    "required": true,
                    "schema": {
                        "type": "string"
                    }
                }
            ],
            "requestBody": {    // <======================  description is lost
                "content": {
                    "text/plain": {
                        "schema": {
                            "type": "string"
                        }
                    }
                }
            },
            "responses": {
                "200": {
                    "description": "OK"
                }
            }
        }
    }
}

How to Reproduce?

  1. Take the https://github.com/quarkusio/quarkus-quickstarts/tree/main/openapi-swaggerui-quickstart project

  2. add a new endpoint to the FruitResource class:

    @PUT
    @Consumes(MediaType.TEXT_PLAIN)
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{fruitName}/description")
    public Response editDescription(
            @Parameter(description = "The name of the fruit", required = true)
            @PathParam("fruitName") String fruitName,
            @RequestBody(description = "The new fruit description", required = true) String description
    ) {
        // ...
        return Response.ok().build();
    }
  3. start the application with ./mvnw quarkus:dev

  4. retrieve the documentation on http://localhost:8080/q/openapi or through Swagger UI

Output of uname -a or ver

No response

Output of java -version

openjdk version "21.0.3" 2024-04-16 LTS

Quarkus version or git rev

3.14.4

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.8.6

Additional information

If you put @RequestBody as the first parameter it works


    @PUT
    @Consumes(MediaType.TEXT_PLAIN)
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{fruitName}/description")
    public Response editDescription(
            @RequestBody(description = "The new fruit description", required = true) String description,
            @Parameter(description = "The name of the fruit", required = true)
            @PathParam("fruitName") String fruitName
    ) {
        // ...
        return Response.ok().build();
    }
quarkus-bot[bot] commented 1 month ago

/cc @EricWittmann (openapi), @MikeEdgar (openapi), @phillip-kruger (openapi)

MikeEdgar commented 1 month ago

I'm looking into this one.