Type Safe
Forget about stringly typed objects, from request to response, everything has types.
Feature Rich
Actix provides a lot of features out of box. HTTP/2, logging, etc.
Extensible
Easily create your own libraries that any Actix application can use.
Blazingly Fast
Actix is blazingly fast. Don't take our word for it -- see for yourself!
Hello World!
Getting started with Actix is easy. An Actix app comes with a URL routing system that lets you match on URLs and invoke individual handlers.
use actix_web::{get, web, App, HttpServer, Responder};
#[get("/")]
async fn index() -> impl Responder {
"Hello, World!"
}
#[get("/{name}")]
async fn hello(name: web::Path<String>) -> impl Responder {
format!("Hello {}!", &name)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().service(index).service(hello))
.bind(("127.0.0.1", 8080))?
.run()
.await
}
Flexible Responders
Handler functions in Actix can return a wide range of objects that implement the Responder trait. This makes it a breeze to return consistent responses from your APIs.
#[derive(Serialize)]
struct Measurement {
temperature: f32,
}
async fn hello_world() -> impl Responder {
"Hello World!"
}
async fn current_temperature() -> impl Responder {
web::Json(Measurement { temperature: 42.3 })
}
Powerful Extractors
Actix comes with a powerful extractor system that extracts data from the incoming HTTP request and passes it to your view functions. Not only does this make for a convenient API but it also means that your view functions can be synchronous code and still benefit from asynchronous IO handling.
#[derive(Deserialize, Serialize)]
struct Event {
id: Option<i32>,
timestamp: f64,
kind: String,
tags: Vec<String>,
}
async fn capture_event(evt: web::Json<Event>) -> impl Responder {
let new_event = store_in_db(evt.timestamp, &evt.kind, &evt.tags);
format!("got event {}", new_event.id.unwrap())
}
Easy Form Handling
Handling JSON or URL-encoded form data is easy. Just define a structure that can be deserialized and Actix will handle the rest.
#[derive(Deserialize)]
struct Register {
username: String,
country: String,
}
// register form is JSON
async fn json_register(form: web::Json<Register>) -> impl Responder {
format!("Hello {} from {}!", form.username, form.country)
}
// register form can be either JSON or URL-encoded
async fn register(form: Either<Json<Register>, Form<Register>>) -> impl Responder {
let Register { username, country } = form.into_inner();
format!("Hello {username} from {country}!")
}
