Génération Swagger/OpenAPI pour Rust : Utoipa — un outil moderne pour la documentation automatique
\n\nLors du développement d'applications web en Rust, la documentation de l'API n'est pas un luxe, mais une nécessité. La bibliothèque Utoipa (abréviation de "Utopia") offre un moyen puissant et élégant de générer des spécifications OpenAPI directement à partir du code. Elle s'intègre avec les frameworks web populaires tels que actix-web, axum, rocket et warp, et permet de décrire les points de terminaison, les schémas de données et les paramètres à l'aide d'attributs et de macros.
Fonctionnalités principales d'Utoipa
\n- \n
- Génération automatique d'OpenAPI 3.0/3.1 — sans rédaction manuelle de YAML/JSON. \n
- Prise en charge de multiples frameworks — actix-web, axum, rocket, warp. \n
- Intégration avec Swagger UI — composant intégré pour la visualisation de la documentation. \n
- Description approfondie des schémas — prise en charge des structures imbriquées, des énumérations, des champs optionnels. \n
- Macros pour une description rapide —
#[utoipa::path],#[openapi]. \n - Validation de la spécification — vérification de l'exactitude du document généré. \n
Installation et configuration
\nAjoutez les dépendances dans Cargo.toml. Pour l'exemple, choisissons le framework actix-web :
[dependencies]\nutoipa = "4"\nutoipa-swagger-ui = { version = "4", features = ["actix-web"] }\nactix-web = "4"\nserde = { version = "1", features = ["derive"] }\n\n\nExemple de base : création d'une API avec documentation
\nConsidérons un CRUD simple pour l'entité "Utilisateur". Commençons par définir le modèle de données :
\nuse serde::{Deserialize, Serialize};\nuse utoipa::ToSchema;\n\n#[derive(Serialize, Deserialize, ToSchema)]\npub struct User {\n #[schema(example = "1")]\n pub id: i32,\n #[schema(example = "john_doe")]\n pub username: String,\n #[schema(example = "john@example.com")]\n pub email: String,\n}\n\nDécrivons maintenant le point de terminaison pour obtenir la liste des utilisateurs à l'aide de la macro #[utoipa::path] :
use actix_web::{get, web, HttpResponse, Responder};\nuse utoipa::OpenApi;\n\n#[utoipa::path(\n get,\n path = "/users",\n responses(\n (status = 200, description = "Liste des utilisateurs", body = Vec<User>)\n )\n)]\n#[get("/users")]\nasync fn get_users() -> impl Responder {\n let users = vec![\n User { id: 1, username: "alice".into(), email: "alice@example.com".into() },\n User { id: 2, username: "bob".into(), email: "bob@example.com".into() },\n ];\n HttpResponse::Ok().json(users)\n}\n\n\nAssemblage du document OpenAPI et de Swagger UI
\nCréons une structure pour décrire l'ensemble de l'API :
\n#[derive(OpenApi)]\n#[openapi(\n paths(get_users),\n components(schemas(User))\n)]\npub struct ApiDoc;\n\n// Dans la fonction main, configurons Swagger UI\nuse utoipa_swagger_ui::SwaggerUi;\n\n#[actix_web::main]\nasync fn main() -> std::io::Result<()> {\n use actix_web::App;\n\n HttpServer::new(|| {\n App::new()\n .service(get_users)\n .service(\n SwaggerUi::new("/swagger-ui/{_:.*}")\n .url("/api-docs/openapi.json", ApiDoc::openapi())\n )\n })\n .bind("127.0.0.1:8080")?\n .run()\n .await\n}\n\nAprès avoir lancé l'application, la documentation sera accessible à l'adresse http://localhost:8080/swagger-ui/.
Fonctionnalités avancées : schémas imbriqués et paramètres
\nUtoipa prend en charge les types de données complexes. Par exemple, ajoutons un champ avec une structure imbriquée :
\n#[derive(Serialize, Deserialize, ToSchema)]\npub struct Address {\n #[schema(example = "Moscou")]\n pub city: String,\n #[schema(example = "rue Lénine, 1")]\n pub street: String,\n}\n\n