Generación Swagger/OpenAPI para Rust: biblioteca Utoipa

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 — herramienta moderna para documentación automática



Al desarrollar aplicaciones web en Rust, la documentación de la API no es un lujo, sino una necesidad. La biblioteca Utoipa (abreviatura de "Utopia") proporciona una forma potente y elegante de generar especificaciones OpenAPI directamente desde el código. Se integra con frameworks web populares como actix-web, axum, rocket y warp, y permite describir endpoints, esquemas de datos y parámetros mediante atributos y macros.



Características principales de Utoipa

  • Generación automática de OpenAPI 3.0/3.1 — sin necesidad de escribir YAML/JSON manualmente.
  • Soporte para múltiples frameworks — actix-web, axum, rocket, warp.
  • Integración con Swagger UI — componente integrado para visualizar la documentación.
  • Descripción profunda de esquemas — soporte para estructuras anidadas, enumeraciones, campos opcionales.
  • Macros para descripción rápida — #[utoipa::path], #[openapi].
  • Validación de especificaciones — verificación de la corrección del documento generado.


Instalación y configuración

Agregue las dependencias en Cargo.toml. Como ejemplo, elegimos el framework actix-web:

[dependencies]utoipa = "4"utoipa-swagger-ui = { version = "4", features = ["actix-web"] }actix-web = "4"serde = { version = "1", features = ["derive"] }


Ejemplo básico: creación de una API con documentación

Consideremos un CRUD simple para la entidad "Usuario". Comencemos definiendo el modelo de datos:

use serde::{Deserialize, Serialize};use utoipa::ToSchema;

#[derive(Serialize, Deserialize, ToSchema)]pub struct User { #[schema(example = "1")] pub id: i32, #[schema(example = "john_doe")] pub username: String, #[schema(example = "john@example.com")] pub email: String,}

Ahora describimos el endpoint para obtener la lista de usuarios usando la macro #[utoipa::path]:

use actix_web::{get, web, HttpResponse, Responder};use utoipa::OpenApi;

#[utoipa::path( get, path = "/users", responses( (status = 200, description = "Lista de usuarios", 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)}


Construcción del documento OpenAPI y Swagger UI

Creamos una estructura para describir toda la API:

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

// En la función main configuramos Swagger UIuse 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}

Después de ejecutar la aplicación, la documentación estará disponible en http://localhost:8080/swagger-ui/.



Funcionalidades avanzadas: esquemas anidados y parámetros

Utoipa admite tipos de datos complejos. Por ejemplo, agreguemos un campo con una estructura anidada:

#[derive(Serialize, Deserialize, ToSchema)]pub struct Address {    #[schema(example = "Moscú")]    pub city: String,    #[schema(example = "Calle Lenin, 1")]    pub street: String,}

Recommendations