Swagger/OpenAPI-Generierung für Rust: Utoipa – modernes Tool für automatische API-Dokumentation
Bei der Entwicklung von Webanwendungen in Rust ist eine gute API-Dokumentation kein Luxus, sondern eine Notwendigkeit. Die Bibliothek Utoipa (Kurzform von "Utopia") bietet eine leistungsstarke und elegante Möglichkeit, OpenAPI-Spezifikationen direkt aus dem Code zu generieren. Sie lässt sich nahtlos in gängige Web-Frameworks wie actix-web, axum, rocket und warp integrieren und ermöglicht die Beschreibung von Endpunkten, Datenschemata und Parametern mittels Attributen und Makros.
Hauptfunktionen von Utoipa
- Automatische Generierung von OpenAPI 3.0/3.1 – kein manuelles Schreiben von YAML/JSON erforderlich.
- Unterstützung mehrerer Frameworks – actix-web, axum, rocket, warp.
- Integration mit Swagger UI – integrierte Komponente zur Visualisierung der Dokumentation.
- Detaillierte Schemabeschreibung – Unterstützung für verschachtelte Strukturen, Aufzählungen und optionale Felder.
- Makros für schnelle Beschreibung –
#[utoipa::path],#[openapi]. - Spezifikationsvalidierung – Prüfung der generierten Dokumentation auf Korrektheit.
Installation und Konfiguration
Fügen Sie die Abhängigkeiten in Ihre Cargo.toml ein. Als Beispiel wählen wir das Framework actix-web:
[dependencies]
utoipa = "4"
utoipa-swagger-ui = { version = "4", features = ["actix-web"] }
actix-web = "4"
serde = { version = "1", features = ["derive"] }
Basisbeispiel: API mit Dokumentation erstellen
Betrachten wir einen einfachen CRUD für die Entität "Benutzer". Beginnen wir mit der Definition des Datenmodells:
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
#[derive(Serialize, Deserialize, ToSchema)]
pub struct User {
#[schema(example = "1")]
pub id: i32,
#[schema(example = "max_mustermann")]
pub username: String,
#[schema(example = "max@example.com")]
pub email: String,
}
Jetzt beschreiben wir den Endpunkt zum Abrufen der Benutzerliste mit dem Makro #[utoipa::path]:
use actix_web::{get, web, HttpResponse, Responder};
use utoipa::OpenApi;
#[utoipa::path(
get,
path = "/users",
responses(
(status = 200, description = "Liste der Benutzer", body = Vec<User>)
)
)]
#[get("/users")]
async fn get_users() -> impl Responder {
let users = vec![
User { id: 1, username: "alice".into(), email: "alice@example.com".into() },
User { id: 2, username: "bob".into(), email: "bob@example.com".into() },
];
HttpResponse::Ok().json(users)
}
OpenAPI-Dokument und Swagger UI erstellen
Erstellen Sie eine Struktur zur Beschreibung der gesamten API:
#[derive(OpenApi)]
#[openapi(
paths(get_users),
components(schemas(User))
)]
pub struct ApiDoc;
// In der main-Funktion konfigurieren wir Swagger UI
use utoipa_swagger_ui::SwaggerUi;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
use actix_web::App;
HttpServer::new(|| {
App::new()
.service(get_users)
.service(
SwaggerUi::new("/swagger-ui/{_:.*}")
.url("/api-docs/openapi.json", ApiDoc::openapi())
)
})
.bind("127.0.0.1:8080")?
.run()
.await
}
Nach dem Start der Anwendung ist die Dokumentation unter http://localhost:8080/swagger-ui/ verfügbar.
Erweiterte Funktionen: verschachtelte Schemata und Parameter
Utoipa unterstützt komplexe Datentypen. Fügen wir beispielsweise ein Feld mit einer verschachtelten Struktur hinzu:
#[derive(Serialize, Deserialize, ToSchema)]
pub struct Address {
#[schema(example = "Berlin")]
pub city: String,
#[schema(example = "Musterstraße 1")]
pub street: String,
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct UserWithAddress {
pub id: i32,
pub username: String,
pub email: String,
pub address: Address,
}
So einfach lassen sich auch komplexe API-Spezifikationen mit Utoipa abbilden. Die Bibliothek ist ideal für alle, die in Rust moderne REST-APIs entwickeln und professionell dokumentieren möchten.
Auch in der Bibliothek
Arbeiten mit Kafka in TypeScript: Die Bibliothek KafkaJS für Node.js
Arbeiten mit Excel in Rust: Bibliotheken und Codebeispiele
Überwachung von Swift-Anwendungen auf iOS/macOS: Bibliotheken und Tools