ActixMiddleTechnical

В чём разница между Actix-web и Axum по архитектуре, производительности и удобству использования?

Actix-web использует собственные трейты Transform/Service и показывает максимальный RPS в бенчмарках; Axum построен на Tower и официально поддерживается командой tokio, обеспечивая богатую экосистему middleware. На практике производительность сопоставима, выбор определяется архитектурными предпочтениями.

Actix-web vs Axum: сравнение архитектур

Оба фреймворка — топ-2 в экосистеме Rust для HTTP-серверов. Они используют tokio в качестве async runtime, поддерживают middleware, extractors и Tower-совместимый стек (Axum нативно, Actix-web через tower-http). Выбор между ними — вопрос архитектурных компромиссов.

Архитектурные различия

Actix-web

  • Собственная система middleware через трейты Transform и Service
  • Extractors через трейт FromRequest (не связан с Tower)
  • Маршрутизация через App + route() / resource() / scope()
  • Работает поверх tokio, но со своим event-loop воркером
  • Более «батарейный» набор из коробки: сессии, мультипарт, WebSocket через actix-web-actors

Axum

  • Построен на Tower — middleware через tower::Layer, совместимые с экосистемой Tower целиком
  • Extractors через трейт FromRequest / FromRequestParts (схоже с Actix, но другой трейт)
  • Маршрутизация через Router с явными вложениями (.nest(), .merge())
  • Zero-cost abstractions — компиляция в монолитный тип; ошибки типов при неправильном стеке
  • Официально поддерживается командой tokio

Сравнение кода: простой хендлер

// Actix-web
use actix_web::{web, HttpResponse};
use serde::Serialize;

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

async fn get_item(path: web::Path<u32>) -> HttpResponse {
    HttpResponse::Ok().json(Item { id: *path, name: "Widget".into() })
}

// App::new().route("/items/{id}", web::get().to(get_item))
// Axum
use axum::{extract::Path, Json};
use serde::Serialize;

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

async fn get_item(Path(id): Path<u32>) -> Json<Item> {
    Json(Item { id, name: "Widget".into() })
}

// Router::new().route("/items/:id", get(get_item))

Сравнение middleware

// Actix-web: собственный Transform трейт (многословно)
// wrap(Logger::default()) для стандартного логирования

// Axum: Tower middleware — лаконично
use tower_http::trace::TraceLayer;
use tower_http::cors::CorsLayer;

let app = Router::new()
    .route("/", get(handler))
    .layer(TraceLayer::new_for_http())
    .layer(CorsLayer::permissive());

Производительность

По бенчмаркам TechEmpower (round 22, plaintext):

  • Actix-web: ~700k–800k RPS (один из лидеров среди всех фреймворков)
  • Axum: ~500k–650k RPS (немного ниже, но разница нивелируется реальным IO)

На практике разница в производительности несущественна — bottleneck почти всегда в базе данных или сети.

Удобство использования

  • Ошибки компиляции: Axum генерирует длинные сообщения о несовместимых типах в стеке; Actix-web — более читаемые ошибки в большинстве случаев
  • Экосистема: Axum использует tower-http (CORS, tracing, compression, auth) — богатый набор готовых слоёв
  • Интеграция с tokio: Axum разработан той же командой, что и tokio; глубже интегрирован
  • WebSocket: Actix-web через actix-web-actors; Axum через axum::extract::ws

Когда выбирать Actix-web

  • Проект уже использует Actix
  • Нужны актив-акторы для WebSocket-чатов
  • Максимальная производительность в тестах важна маркетингово

Когда выбирать Axum

  • Новый проект с нуля
  • Нужна совместимость с Tower middleware (tower-http, tower-sessions и т.д.)
  • Команда ценит типобезопасность и тесную интеграцию с tokio

Подводные камни

  • Axum ошибки типов — неправильный порядок extractors или несовместимый State приводит к эссе на несколько экранов от компилятора.
  • Actix Transform — сложный API — написание custom middleware в Actix verbose и требует понимания Rc/Service/Transform.
  • Миграция между фреймворками — несмотря на похожий API, код не переносится без переписывания; выбирайте заранее осознанно.
  • actix-web-actors deprecated direction — команда Actix не развивает акторную модель активно; для WebSocket в новых проектах Axum может быть предпочтительнее.
  • Версионирование tower-http — Axum жёстко привязан к конкретной версии Tower; несовместимость версий в transitive зависимостях — частая проблема.

Common mistakes

  • Отвечать определением без production-сценария.
  • Не называть runtime boundary, security boundary или failure mode.
  • Игнорировать версию API, observability и тестовую проверку.

What the interviewer is testing

  • Объясняет механизм своими словами и без выдуманных API.
  • Называет реальные риски, диагностику и критерий корректности.
  • Связывает ответ с текущей документацией и миграционными ограничениями.

Sources

Related topics