juhaku / utoipa

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

Axum example does not work.... still #1033

Closed ipconfiger closed 2 days ago

ipconfiger commented 1 week ago

Cargo.toml

utoipa = { version = "4.2.3", features = [
    "axum_extras",
    "debug",
    "chrono",
    "time",
    "uuid",
    "decimal",
    "url", ] }
utoipa-swagger-ui = { version = "=7.1.0", features = ["axum",] }

Code:

use utoipa::OpenApi;
use utoipa_swagger_ui::SwaggerUi;

...

    let app = Router::new()
        .merge(SwaggerUi::new("/api/docs/ui")
            .url("/api/docs/openapi.json", ApiDoc::openapi()))
        .route("/api/docs/openapi.json", get(openapi))
        ...
        .with_state(state);

Build result:

error[E0277]: the trait bound `Router<_, _>: From<SwaggerUi>` is not satisfied
   --> src/app.rs:50:16
    |
50  |           .merge(SwaggerUi::new("/api/docs/ui")
    |  __________-----_^
    | |          |
    | |          required by a bound introduced by this call
51  | |             .url("/api/docs/openapi.json", ApiDoc::openapi()));
    | |_____________________________________________________________^ the trait `From<SwaggerUi>` is not implemented for `Router<_, _>`, which is required by `SwaggerUi: Into<Router<_, _>>`
    |
    = note: required for `SwaggerUi` to implement `Into<Router<_, _>>`
note: required by a bound in `Router::<S, B>::merge`

What i miss?

juhaku commented 1 week ago

Full cargo.toml

[package]
name = "utoipa-test"
version = "0.1.0"
edition = "2021"

[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
tower = "0.5"
utoipa = { version = "4", features = ["axum_extras"] }
utoipa-swagger-ui = { version = "7", features = ["axum"] }

Full rust code main.rs

use std::net::Ipv4Addr;

use axum::{routing, Router};
use tokio::net::TcpListener;
use utoipa::OpenApi;
use utoipa_swagger_ui::SwaggerUi;

#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
    let app: Router = Router::new()
        .route("/health", routing::get(health))
        .merge(SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", ApiDoc::openapi()));

    let listener = TcpListener::bind((Ipv4Addr::LOCALHOST, 8080)).await?;
    axum::serve(listener, app).await
}

#[derive(OpenApi)]
#[openapi(paths(health))]
struct ApiDoc;

#[utoipa::path(
    get,
    path = "/health",
    responses(
        (status = OK, description = "Success", body = str)
    )
)]
async fn health() -> &'static str {
    "OK"
}

Screenshot from 2024-09-08 11-11-10 image

The above will work as shown in the images.

Have you tried cargo clean. That error indicates that the SwaggerUi does not implement axum Router trait. However the utoipa-swagger-ui does provide this implementation with axum feature flag.

Have you tried to debug with cargo tree --format "{p} {f}" to see what features gets where?

ipconfiger commented 5 days ago

OK, tks, will try it

juhaku commented 2 days ago

@ipconfiger Can this be considered solved?

ipconfiger commented 2 days ago

cargo clean works,tks