Generación Swagger/OpenAPI para Rust: Utoipa y Aide

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Generación Swagger/OpenAPI para Rust: Utoipa y Aide



En el desarrollo web moderno con Rust, crear una API documentada no es un lujo, sino una necesidad. Swagger (OpenAPI) permite generar automáticamente documentación interactiva, SDK de cliente y consolas de prueba. En el ecosistema de Rust, dos herramientas ocupan las posiciones líderes: Utoipa (basada en macros) y Aide (con énfasis en la tipificación y el control manual). Analicémoslas en detalle.



Utoipa — macros para OpenAPI 3.0



Utoipa es una biblioteca que utiliza macros de atributos (#[utoipa::path]) para la generación automática de especificaciones OpenAPI. Se integra estrechamente con frameworks populares: Actix-web, Axum, Rocket, Warp.



Características:

  • Soporte completo de OpenAPI 3.0 (paths, components, security schemes).
  • Extracción automática de tipos de estructuras de Rust (con #[derive(ToSchema)]).
  • Generación de archivos JSON/YAML para Swagger UI.
  • Soporte para actix-web listo para usar (a través de utoipa-swagger-ui).
  • Baja barrera de entrada: basta con agregar macros.


Ejemplo con Actix-web:

use actix_web::{get, web, App, HttpResponse, HttpServer, Responder};use serde::{Deserialize, Serialize};use utoipa::{OpenApi, ToSchema};use utoipa_swagger_ui::SwaggerUi;

#[derive(Serialize, Deserialize, ToSchema)]struct User { id: u32, name: String,}

#[utoipa::path( get, path = "/users/{id}", responses( (status = 200, description = "User found", body = User), (status = 404, description = "User not found") ), params( ("id" = u32, Path, description = "User ID") ))]#[get("/users/{id}")]async fn get_user(id: web::Path<u32>) -> impl Responder { HttpResponse::Ok().json(User { id: id.into_inner(), name: "Alice".into(), })}

#[derive(OpenApi)]#[openapi(paths(get_user), components(schemas(User)))]struct ApiDoc;

#[actix_web::main]async fn main() -> std::io::Result<()> { HttpServer::new(|| { App::new() .service(get_user) .service( SwaggerUi::new("/swagger-ui/{_:.*}") .url("/api-doc/openapi.json", ApiDoc::openapi()), ) }) .bind("127.0.0.1:8080")? .run() .await}


Aide — control y tipificación



Aide (anteriormente paperclip) ofrece un enfoque diferente: describes explícitamente la especificación a través de estructuras y funciones, en lugar de mediante macros. Esto proporciona más control, pero requiere más código. La biblioteca es compatible con Axum y Actix-web.



Características:

  • Tipificación limpia: todas las descripciones se definen mediante enum y struct.
  • Validación de esquemas integrada durante la generación.
  • Soporte para modelos anidados y composiciones (allOf, oneOf).
  • Flexibilidad: se puede sobrescribir cualquier aspecto de la especificación.


Ejemplo con Axum:

use aide::{axum::ApiRouter, openapi::OpenApi};use axum::{routing::get, Json, Router};use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]struct Pet { id: u32, name: String,}

async fn list_pets() -> Json<Vec<Pet>> { Json(vec![Pet { id: 1, name: "Rex".into(), }])}

async fn api_docs() -> Json<OpenApi> { let mut api = OpenApi::default(); api.info.title = "Pet Store API".into(); api.info.version = "1.0.0".into(); Json(api)}

#[tokio::main]async fn main() { let app = ApiRouter::new() .route("/pets", get(list_pets)) .route("/api-doc", get(api_docs));

axum::Server::bind(&"0.0.0.0:3000".parse().unwrap()) .serve(app.into_make_service()) .await .unwrap();}

Recommendations