Swagger/OpenAPI генерация для Rust: Utoipa и Aide

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Swagger/OpenAPI генерация для Rust: Utoipa и Aide

В современной веб-разработке на Rust создание документированного API — не роскошь, а необходимость. Swagger (OpenAPI) позволяет автоматически генерировать интерактивную документацию, клиентские SDK и тестовые консоли. В экосистеме Rust лидирующие позиции занимают два инструмента: Utoipa (на основе макросов) и Aide (с акцентом на типизацию и ручной контроль). Рассмотрим их подробно.

Utoipa — макросы для OpenAPI 3.0

Utoipa — это библиотека, которая использует атрибуты-макросы (#[utoipa::path]) для автоматической генерации OpenAPI спецификации. Она плотно интегрируется с популярными фреймворками: Actix-web, Axum, Rocket, Warp.

Особенности:

  • Полная поддержка OpenAPI 3.0 (paths, components, security schemes).
  • Автоматическое извлечение типов из структур Rust (с помощью #[derive(ToSchema)]).
  • Генерация JSON/YAML файла для Swagger UI.
  • Поддержка actix-web из коробки (через utoipa-swagger-ui).
  • Низкий порог входа — достаточно добавить макросы.

Пример с 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 — контроль и типизация

Aide (ранее paperclip) предлагает другой подход: вы явно описываете спецификацию через структуры и функции, а не через макросы. Это даёт больше контроля, но требует большего объёма кода. Библиотека поддерживает Axum и Actix-web.

Особенности:

  • Чистая типизация — все описания задаются через enum и struct.
  • Встроенная валидация схем при генерации.
  • Поддержка вложенных моделей и композиций (allOf, oneOf).
  • Гибкость: можно переопределить любой аспект спецификации.

Пример с 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();
}

Сравнение Utoipa vs Aide

  • Простота: Utoipa выигрывает за счёт макросов — достаточно аннотировать хендлеры. Aide требует ручного описания.
  • Контроль: Aide даёт полный контроль над спецификацией, что полезно для сложных API с кастомными валидациями.
  • Эк

Рекомендаций