juhaku / utoipa

Simple, Fast, Code first and Compile time generated OpenAPI documentation for Rust
Apache License 2.0
2k stars 160 forks source link

Default tag does not get overriden. #955

Open EinarasGar opened 3 weeks ago

EinarasGar commented 3 weeks ago

Hi, Im trying out version 5.0.0-alpha.0 and have noticed new behavior with tags. As mentioned in #916

This means that the default tag (the handler function name by default) will be added if not overridden with the tag attribute.

However, I do not experience this behavior. Using this configuration

#[derive(OpenApi)]
#[openapi(
    paths(
        super::handlers::accounts_handler::get_account,
         ...
    ),

and

/// Get Account
///
/// Gets a specific account of the user with metadata.
#[utoipa::path(
    get,
    path = "/api/users/:user_id/accounts/:account_id",
    tag = "Accounts",
    responses(
        ...
    ),
    params(
        ...
    ),
    security(
      ...
    )

)]
pub async fn get_account(

My openapi spec generates like this

"/api/users/:user_id/accounts/:account_id": {
      "get": {
        "tags": [
          "Accounts",
          "super::handlers::accounts_handler"
        ],
        "summary": "Get Account",
        "description": "Gets a specific account of the user with metadata.",
        "operationId": "get_account",
...

This results in my redoc view having double of everything.

Reproducable example can be found here https://github.com/EinarasGar/myra/blob/crate-update/server/api/src/openapi.rs https://github.com/EinarasGar/myra/blob/crate-update/server/api/src/handlers/accounts_handler.rs

NickUfer commented 3 weeks ago

Got the same problem. You have to add an import statement for what you are using as a path or an api. In your case this should fix it, if super:: works the same as crate:: :

use super::handlers::accounts_handler::get_account;

#[derive(OpenApi)]
#[openapi(
    paths(
        get_account,
         ...
    ),
eiswind commented 1 week ago

I see the same issue here. But my handler and the #[derive(OpenApi)] are in the same module, so I do not need to import. In the generated spec I see my custom tag, as well as the module name.

#[derive(OpenApi)]
#[openapi(
    tags((name = "Authentication", description = "Authentication operations")),
    paths(authenticate),
    components(schemas(
      ...
    ))
)]