Rust untuk Web: Perbandingan Actix Web vs Axum dan Pertanyaan Wawancara 2026

Perbandingan praktis Actix Web 4.14 dan Axum 0.8 untuk pengembangan web Rust di tahun 2026. Arsitektur, benchmark TechEmpower Round 23, pengalaman developer, dan pertanyaan wawancara untuk posisi backend Rust.

Perbandingan Rust Actix Web vs Axum

Adopsi framework web Rust telah meningkat tajam di tahun 2026, dan dua framework mendominasi deployment production: Actix Web 4.14 dan Axum 0.8. Pemilihan antara keduanya memengaruhi segala hal mulai dari onboarding tim hingga throughput production, dan pertanyaan ini sering muncul dalam wawancara backend Rust.

Kerangka Keputusan Cepat

Actix Web 4.14 unggul dalam raw throughput (10-15% lebih banyak request/detik di bawah beban berat). Axum 0.8 menyediakan ergonomi yang lebih baik melalui native async traits, komposabilitas middleware Tower, dan integrasi Tokio yang lebih erat. Untuk sebagian besar tim yang memulai proyek baru di tahun 2026, Axum adalah pilihan pragmatis kecuali kebutuhan throughput ekstrem menentukan sebaliknya.

Perbedaan Arsitektur antara Actix Web dan Axum

Divergensi arsitektur antara kedua framework ini menjelaskan sebagian besar trade-off performa dan ergonomi.

Actix Web menjalankan N runtime Tokio single-threaded, satu per core fisik. Task dipasang ke thread tanpa migrasi data lintas-thread. Hal ini menghilangkan overhead work-stealing dan cache-line bouncing, yang menjelaskan keunggulan throughput yang konsisten di bawah beban berkelanjutan.

Axum berjalan pada satu runtime Tokio multi-threaded dengan work-stealing. Tim Tokio membangun Axum secara khusus untuk menampilkan kemampuan runtime, sehingga setiap keputusan desain mengoptimalkan komposabilitas dengan ekosistem Tokio yang lebih luas. Handler adalah fungsi async biasa, dan middleware menggunakan trait Service milik Tower.

actix_hello.rs - Actix Web minimal serverrust
use actix_web::{web, App, HttpServer, HttpResponse};

async fn health() -> HttpResponse {
    HttpResponse::Ok().json(serde_json::json!({ "status": "ok" }))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .route("/health", web::get().to(health))
    })
    .bind("0.0.0.0:8080")?
    .run()
    .await
}
axum_hello.rs - Axum minimal serverrust
use axum::{Router, Json, routing::get};
use serde_json::{json, Value};

async fn health() -> Json<Value> {
    Json(json!({ "status": "ok" }))
}

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/health", get(health));

    let listener = tokio::net::TcpListener::bind("0.0.0.0:8080")
        .await
        .unwrap();
    axum::serve(listener, app).await.unwrap();
}

Kedua contoh dapat dikompilasi dan dijalankan, namun perbedaannya sudah terlihat. Actix Web menggunakan makro #[actix_web::main] sendiri dan mengembalikan std::io::Result. Axum menggunakan #[tokio::main] standar dan membangun route melalui struct Router. Handler Axum mengembalikan typed extractor (Json<Value>) alih-alih membangun HttpResponse secara manual.

Benchmark Performa: Actix Web 4.14 vs Axum 0.8

Data benchmark dari TechEmpower Round 23 (Januari 2026) memberikan perbandingan paling andal. Kedua framework berada di tier teratas di semua kategori.

MetrikActix Web 4.14Axum 0.8.9
Plaintext (req/s)~7.100.000~6.200.000
JSON serialization (req/s)~1.200.000~1.050.000
DB single query (req/s)~190.000~175.000
Memory usage (hello world)~8 MB~6 MB
P99 latency (JSON)1,1 ms1,3 ms

Actix Web mempertahankan keunggulan throughput 10-15% di semua kategori. Axum menggunakan memori sedikit lebih sedikit karena shared Tokio runtime. Sebagai konteks, kedua framework mengungguli HTTP server standar Go sebesar 2-3x dan Node.js sebesar 5-8x pada hardware yang setara.

Kesenjangan performa penting untuk ad serving, pipeline analitik real-time, dan gateway high-frequency trading. Untuk REST API tipikal yang melayani 10.000 request/detik, kedua framework jauh melampaui bottleneck, yang akan menjadi database atau panggilan layanan eksternal.

Extractor dan Penanganan Request Dibandingkan

Extractor mendefinisikan bagaimana framework mem-parsing request yang masuk. Axum 0.8 melakukan perbaikan signifikan di sini dengan menghapus #[async_trait] demi native async traits dan memperkenalkan OptionalFromRequestParts untuk penanganan Option<T> yang lebih baik.

axum_extractors.rs - Axum 0.8 extractor patternrust
use axum::{
    extract::{Path, Query, State, Json},
    routing::get,
    Router,
};
use serde::Deserialize;
use std::sync::Arc;

#[derive(Deserialize)]
struct Pagination {
    page: Option<u32>,    // defaults to None if missing
    per_page: Option<u32>,
}

// State shared across handlers
struct AppState {
    db_pool: sqlx::PgPool,
}

// Axum 0.8: /{id} syntax (replaced /:id)
async fn get_user(
    State(state): State<Arc<AppState>>,
    Path(user_id): Path<i64>,
    Query(pagination): Query<Pagination>,
) -> Json<serde_json::Value> {
    let page = pagination.page.unwrap_or(1);
    // Query database using state.db_pool
    Json(serde_json::json!({
        "user_id": user_id,
        "page": page
    }))
}
actix_extractors.rs - Actix Web extractor patternrust
use actix_web::{web, HttpResponse};
use serde::Deserialize;

#[derive(Deserialize)]
struct Pagination {
    page: Option<u32>,
    per_page: Option<u32>,
}

struct AppState {
    db_pool: sqlx::PgPool,
}

async fn get_user(
    state: web::Data<AppState>,
    path: web::Path<i64>,
    query: web::Query<Pagination>,
) -> HttpResponse {
    let user_id = path.into_inner();
    let page = query.page.unwrap_or(1);
    HttpResponse::Ok().json(serde_json::json!({
        "user_id": user_id,
        "page": page
    }))
}

Extractor Axum menggunakan tuple destructuring langsung di parameter fungsi. Actix Web membungkus semuanya dalam web::Path, web::Query, dll., memerlukan pemanggilan .into_inner(). Kedua pendekatan type-safe saat kompilasi, namun pendekatan Axum terbaca lebih natural.

Perubahan Breaking Axum 0.8

Parameter path beralih dari sintaks /:id ke /{id} di Axum 0.8 (melalui matchit 0.8). Ini selaras dengan sintaks path OpenAPI. Escape menggunakan kurung kurawal ganda: {{ untuk literal {.

Arsitektur Middleware: Tower vs Actix Middleware

Komposisi middleware adalah di mana perbedaan arsitektur menghasilkan dampak praktis paling besar.

Axum menggunakan trait Service dan Layer milik Tower. Middleware apa pun yang kompatibel dengan Tower bekerja dengan Axum, termasuk rate limiter, tracing, kompresi, dan layer autentikasi yang dibangun untuk layanan berbasis Tower lainnya. Komposabilitas ini melampaui HTTP; middleware yang sama dapat membungkus layanan gRPC melalui Tonic.

axum_middleware.rs - Tower middleware compositionrust
use axum::{
    Router, middleware,
    routing::get,
    extract::Request,
    response::Response,
};
use tower_http::{
    cors::CorsLayer,
    compression::CompressionLayer,
    trace::TraceLayer,
};
use std::time::Instant;

// Custom middleware as a plain async function
async fn timing_middleware(
    request: Request,
    next: middleware::Next,
) -> Response {
    let start = Instant::now();
    let response = next.run(request).await;
    let duration = start.elapsed();
    tracing::info!("Request took {:?}", duration);
    response
}

fn build_router() -> Router {
    Router::new()
        .route("/api/data", get(|| async { "ok" }))
        .layer(middleware::from_fn(timing_middleware))
        .layer(CompressionLayer::new())
        .layer(CorsLayer::permissive())
        .layer(TraceLayer::new_for_http())
}

Actix Web menggunakan sistem middleware sendiri dengan trait Transform dan Service (bukan milik Tower). Middleware dari ekosistem Tower yang lebih luas memerlukan adapter atau penulisan ulang.

Untuk tim yang sudah berinvestasi di ekosistem Tower melalui Tonic (gRPC) atau Hyper, middleware Axum merupakan keunggulan signifikan. Untuk tim yang membangun layanan HTTP mandiri, sistem middleware Actix Web sama mampunya, hanya tidak dapat dipertukarkan.

Actix Web 4.14 memperkenalkan validasi route middleware yang panic jika handler ditambahkan setelah pembungkusan middleware, menangkap kesalahan konfigurasi saat startup alih-alih runtime.

Siap menguasai wawancara Rust Anda?

Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.

Integrasi Database dengan SQLx

Kedua framework berpasangan dengan baik dengan SQLx, toolkit SQL async-first yang memvalidasi query saat kompilasi. Pola integrasinya sedikit berbeda.

shared_db.rs - SQLx with compile-time query validationrust
use sqlx::PgPool;

// This struct works identically with Actix Web and Axum
#[derive(sqlx::FromRow, serde::Serialize)]
struct User {
    id: i64,
    email: String,
    created_at: chrono::NaiveDateTime,
}

// sqlx::query_as! validates against a live DB at compile time
async fn find_user_by_email(
    pool: &PgPool,
    email: &str,
) -> Result<Option<User>, sqlx::Error> {
    sqlx::query_as!(
        User,
        "SELECT id, email, created_at FROM users WHERE email = $1",
        email
    )
    .fetch_optional(pool)
    .await
}

Layer database tetap identik terlepas dari pilihan framework. Makro query_as! SQLx terhubung ke database live saat kompilasi dan memvalidasi nama kolom, tipe, dan keberadaan tabel. Typo pada nama kolom menghasilkan error kompilasi, bukan crash runtime.

Pola Penanganan Error Dibandingkan

Penanganan error mengungkapkan filosofi desain yang berbeda. Actix Web menggunakan implementasi trait ResponseError. Axum mengandalkan IntoResponse dikombinasikan dengan tipe Result.

axum_errors.rs - Axum error handling with IntoResponserust
use axum::{
    http::StatusCode,
    response::{IntoResponse, Response},
    Json,
};

// Define application-level errors
enum AppError {
    NotFound(String),
    DatabaseError(sqlx::Error),
    ValidationError(String),
}

// Convert errors into HTTP responses
impl IntoResponse for AppError {
    fn into_response(self) -> Response {
        let (status, message) = match self {
            AppError::NotFound(msg) => (
                StatusCode::NOT_FOUND, msg
            ),
            AppError::DatabaseError(_) => (
                StatusCode::INTERNAL_SERVER_ERROR,
                "Internal server error".to_string(),
            ),
            AppError::ValidationError(msg) => (
                StatusCode::BAD_REQUEST, msg
            ),
        };
        (status, Json(serde_json::json!({ "error": message })))
            .into_response()
    }
}

// Handlers return Result<T, AppError>
async fn get_user(
    axum::extract::Path(id): axum::extract::Path<i64>,
) -> Result<Json<serde_json::Value>, AppError> {
    if id <= 0 {
        return Err(AppError::ValidationError(
            "ID must be positive".to_string()
        ));
    }
    Ok(Json(serde_json::json!({ "id": id })))
}

Pendekatan Axum berkomposisi secara natural dengan operator ? Rust dan tipe Result. Actix Web mencapai hal yang sama melalui ResponseError, yang memerlukan implementasi trait Display dan ResponseError. Keduanya bekerja, namun pola Axum terasa lebih idiomatis bagi developer Rust yang terbiasa dengan trait From dan propagasi error.

Kapan Memilih Actix Web daripada Axum

Actix Web tetap menjadi pilihan tepat dalam skenario tertentu:

  • Kebutuhan throughput maksimum: Ad exchange, real-time bidding, pipeline ingestion analitik di mana 10-15% lebih banyak req/s membenarkan trade-off.
  • Aplikasi intensif WebSocket: Dukungan WebSocket Actix Web telah teruji di lebih banyak deployment production. Dukungan WebSocket Axum (melalui axum::extract::ws) bekerja dengan baik namun memiliki track record production yang lebih pendek.
  • Codebase Actix Web yang sudah ada: Migrasi dari Actix Web 3.x ke 4.x straightforward. Menulis ulang ke Axum menawarkan diminishing returns untuk layanan yang stabil.
  • Familiaritas tim: Jika tim sudah mengetahui Actix Web, berpindah framework untuk keuntungan ergonomi jarang memberikan hasil dalam jangka pendek.

Kapan Memilih Axum daripada Actix Web

Axum lebih cocok dalam konteks ini:

  • Proyek baru di tahun 2026: Keselarasan ekosistem Tokio (Tonic, Hyper, Tower) mengurangi friction integrasi.
  • Layanan campuran gRPC dan HTTP: Middleware Tower bekerja di kedua protokol tanpa layer adaptasi.
  • Tim baru di Rust: Extractor berbasis tipe dan pesan error compile-time Axum menyediakan kurva belajar yang lebih landai. Sintaks path /{id} (selaras dengan OpenAPI) langsung familiar.
  • Arsitektur microservice: Trait Service Tower memungkinkan reuse middleware lintas layanan, mengurangi boilerplate.

Pertanyaan Wawancara: Actix Web dan Axum untuk Posisi Backend Rust

Pertanyaan wawancara Rust backend semakin mencakup pengetahuan web framework. Pertanyaan-pertanyaan ini muncul dalam wawancara backend senior dan systems engineering.

P: Jelaskan perbedaan arsitektur antara model runtime Actix Web dan Axum.

Actix Web menjalankan satu runtime Tokio single-threaded per core CPU. Task dipasang ke thread, menghilangkan overhead work-stealing. Axum berjalan pada shared runtime Tokio multi-threaded dengan work-stealing. Model Actix Web mengurangi cache-line contention di bawah beban berat, menghasilkan throughput lebih tinggi. Model Axum menyederhanakan manajemen shared state karena semua task berbagi satu runtime.

P: Bagaimana penghapusan #[async_trait] di Axum 0.8 memengaruhi custom extractor?

Axum 0.8 memanfaatkan return-position impl Trait native di traits Rust (distabilkan akhir 2023). Custom extractor yang mengimplementasikan FromRequestParts atau FromRequest sekarang mendefinisikan metode async secara langsung tanpa atribut #[async_trait]. Ini menghilangkan alokasi heap dari Box<dyn Future> dan meningkatkan waktu kompilasi. Extractor yang ada memerlukan penghapusan makro dan penyesuaian implementasi trait.

P: Jelaskan bagaimana middleware Tower berbeda dari middleware Actix Web.

Tower mendefinisikan trait Service<Request> generik yang protocol-agnostic. Layer timeout Tower bekerja dengan HTTP (Axum), gRPC (Tonic), dan protokol kustom apa pun. Middleware Actix Web menggunakan trait Transform dan Service yang spesifik untuk framework-nya. Dampak praktisnya: middleware Axum dapat digunakan ulang di seluruh ekosistem Tower; middleware Actix Web spesifik untuk framework.

P: Bagaimana cara kerja validasi query compile-time SQLx, dan apa trade-off-nya?

Makro query_as! SQLx terhubung ke database PostgreSQL live selama kompilasi. Ini memvalidasi sintaks SQL, nama kolom, tipe, dan keberadaan tabel. Trade-off: build memerlukan akses database, yang menyulitkan pipeline CI. SQLx menyediakan sqlx prepare untuk menghasilkan metadata query offline, menyimpan hasil validasi dalam direktori .sqlx yang di-commit ke version control.

P: Kapan memilih Actix Web daripada Axum merupakan keputusan teknis yang benar?

Actix Web benar ketika throughput berkelanjutan adalah constraint utama: ad serving, ingestion analitik real-time, atau gateway high-frequency trading. Model runtime pinned-thread menghilangkan overhead work-stealing, menghasilkan 10-15% lebih tinggi req/s di bawah beban. Axum benar ketika komposabilitas dengan ekosistem Tokio lebih penting daripada keuntungan throughput marginal, terutama dalam arsitektur microservice yang menggunakan HTTP dan gRPC.

Kesalahan Umum dalam Wawancara

Kandidat sering mengklaim satu framework secara universal lebih baik. Jawaban kuat mengakui trade-off: Actix Web mengoptimalkan untuk throughput, Axum mengoptimalkan untuk komposabilitas ekosistem. Pilihan yang tepat tergantung pada constraint sistem, bukan preferensi pribadi.

Sumber

Poin Penting untuk Pengembangan Web Rust di 2026

  • Actix Web 4.14 memberikan throughput 10-15% lebih tinggi melalui model runtime pinned-thread, menjadikannya pilihan tepat untuk layanan yang sensitif latensi dan throughput tinggi
  • Axum 0.8 menyediakan ergonomi lebih baik dengan native async traits, sintaks path /{id}, dan kompatibilitas penuh middleware Tower lintas HTTP dan gRPC
  • Kedua framework menggunakan layer database yang sama (SQLx dengan validasi compile-time), sehingga pilihan tidak memengaruhi pola akses data
  • Untuk proyek web Rust baru di tahun 2026 tanpa kebutuhan throughput ekstrem, keselarasan ekosistem Axum dengan Tokio, Tonic, dan Tower mengurangi biaya pemeliharaan jangka panjang
  • Pertanyaan wawancara tentang topik ini menguji pemahaman tentang model runtime, arsitektur middleware, dan penalaran trade-off, bukan preferensi framework
  • Persiapan wawancara Rust memerlukan pemahaman keputusan arsitektur kedua framework, bukan hanya sintaks API

Mulai berlatih!

Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.

Tantangan harian

Bisakah kamu menemukan bug di Rust?

Satu potongan kode nyata, satu bug tersembunyi, satu percobaan per hari. Tanpa akun untuk mencoba.

Anthony Fillion-Maillet

Ditulis oleh

Anthony Fillion-Maillet

Pendiri SharpSkill

Developer fullstack selama lebih dari 10 tahun. Ia menjalankan SharpSkill dan bertanggung jawab atas semua yang diterbitkan di sini.

Diperbarui 22 Agustus 2026

Tag

#rust
#actix-web
#axum
#web-framework
#backend
#comparison

Bagikan

Artikel terkait