DEV Community

Alex Spinov
Alex Spinov

Posted on

Actix Web Has a Free API — Rust's Fastest Web Framework

Actix Web is the fastest web framework in most benchmarks — period. Built on Rust's async runtime with Tokio, it handles millions of requests with minimal memory.

Why Actix Web?

  • #1 in TechEmpower benchmarks for multiple rounds
  • Type-safe — compile-time route and handler validation
  • Middleware system — composable, async middleware
  • WebSocket support — built-in, first-class

Quick Start

cargo new myapi && cd myapi
cargo add actix-web serde --features serde/derive
Enter fullscreen mode Exit fullscreen mode
use actix_web::{web, App, HttpServer, HttpResponse};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct Info {
    name: String,
}

async fn hello(info: web::Query<Info>) -> HttpResponse {
    HttpResponse::Ok().json(serde_json::json!({
        "message": format!("Hello, {}!", info.name)
    }))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .route("/hello", web::get().to(hello))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}
Enter fullscreen mode Exit fullscreen mode

JSON API with Extractors

#[derive(Deserialize)]
struct CreateUser {
    name: String,
    email: String,
}

#[derive(Serialize)]
struct User {
    id: u64,
    name: String,
    email: String,
}

async fn create_user(body: web::Json<CreateUser>) -> HttpResponse {
    let user = User {
        id: 1,
        name: body.name.clone(),
        email: body.email.clone(),
    };
    HttpResponse::Created().json(user)
}

async fn get_user(path: web::Path<u64>) -> HttpResponse {
    let id = path.into_inner();
    HttpResponse::Ok().json(User {
        id,
        name: "Alice".into(),
        email: "alice@example.com".into(),
    })
}

// Route configuration
App::new()
    .route("/users", web::post().to(create_user))
    .route("/users/{id}", web::get().to(get_user))
Enter fullscreen mode Exit fullscreen mode

Middleware

use actix_web::middleware::{Logger, Compress};
use actix_cors::Cors;

App::new()
    .wrap(Logger::default())
    .wrap(Compress::default())
    .wrap(
        Cors::default()
            .allow_any_origin()
            .allow_any_method()
            .allow_any_header()
    )
Enter fullscreen mode Exit fullscreen mode

Shared State

use std::sync::Mutex;

struct AppState {
    counter: Mutex<i32>,
}

async fn increment(data: web::Data<AppState>) -> HttpResponse {
    let mut counter = data.counter.lock().unwrap();
    *counter += 1;
    HttpResponse::Ok().json(serde_json::json!({ "count": *counter }))
}

HttpServer::new(|| {
    let state = web::Data::new(AppState {
        counter: Mutex::new(0),
    });
    App::new()
        .app_data(state)
        .route("/count", web::post().to(increment))
})
Enter fullscreen mode Exit fullscreen mode

Building high-performance data pipelines? Check out my Apify actors for web scraping at scale, or email spinov001@gmail.com for custom Rust solutions.

Actix Web, Axum, or Rocket — which is your Rust framework? Comment below!

Top comments (0)