Skip to content

Instantly share code, notes, and snippets.

@sheepla
Last active June 22, 2025 12:06
Show Gist options
  • Select an option

  • Save sheepla/bbc9b75f2cec7671b7ecdaa4603a3d92 to your computer and use it in GitHub Desktop.

Select an option

Save sheepla/bbc9b75f2cec7671b7ecdaa4603a3d92 to your computer and use it in GitHub Desktop.
Generating OpenAPI doc with Utoipa + Scalar + Axum in Rust
[package]
name = "utoipa_scalar_example"
version = "0.1.0"
edition = "2024"
[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
utoipa = { version = "4", features = ["axum_extras"] }
utoipa-swagger-ui = "5"
utoipa-scalar = { version = "0.1", features = ["axum"] }
serde = { version = "1", features = ["derive"] }
use axum::{Json, Router, routing::get};
use serde::{Deserialize, Serialize};
use tokio::net::TcpListener;
use utoipa::OpenApi;
use utoipa_scalar::Scalar;
#[derive(Serialize, Deserialize, utoipa::ToSchema)]
struct HelloResponse {
message: String,
}
#[utoipa::path(
get,
path = "/hello",
responses((status = 200, body = HelloResponse))
)]
async fn hello() -> Json<HelloResponse> {
Json(HelloResponse {
message: "Hello from Scalar!".to_string(),
})
}
#[derive(OpenApi)]
#[openapi(paths(hello), components(schemas(HelloResponse)))]
struct ApiDoc;
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/hello", get(hello))
.nest("/scalar", Scalar::new(ApiDoc::openapi()).into());
let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap();
println!("→ Open http://localhost:3000/scalar");
axum::serve(listener, app).await.unwrap();
}
@sheepla
Copy link
Copy Markdown
Author

sheepla commented Jun 22, 2025

Result

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment