Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction aux Frameworks web (axum / actix)

Rust est reconnu pour :

  • ses performantes,
  • la sécurité mémoire et
  • sa faible empreinte de ressources.

Deux frameworks dominent aujourd’hui le paysage pour le développement d’API et de services web backend :

  • Actix Web : historique, ultra-rapide, basé sur les acteurs et
  • Axum : moderne, développé par l’équipe Tokio, basé sur la composition.

Axum : Le framework moderne de l’écosystème Tokio

Axum intègre l’écosystème tokio et les middlewares tower.

  • Routage déclaratif : Les routes sont chaînées de manière fluide.
  • Extracteurs (Extractors) : Les arguments des fonctions de gestion (handlers) déterminent automatiquement ce qui doit être extrait de la requête (JSON, paramètres, headers) grâce au système de types de Rust.
use axum::{routing::{get, post}, Json, Router};
use serde::{Deserialize, Serialize};

#[derive(Deserialize)]
struct NouvelUtilisateur {
    nom: String,
}

#[derive(Serialize)]
struct Utilisateur {
    id: u64,
    nom: String,
}

#[tokio::main]
async fn main() {
    // Construction des routes
    let app = Router::new()
        .route("/", get(racine))
        .route("/utilisateurs", post(creer_utilisateur));

    // Lancement du serveur avec Tokio
    let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

async fn racine() -> &'static str {
    "Bienvenue sur l'API Axum !"
}

// L'argument Json<NouvelUtilisateur> est un extracteur
async fn creer_utilisateur(Json(payload): Json<NouvelUtilisateur>) -> Json<Utilisateur> {
    let utilisateur = Utilisateur {
        id: 1,
        nom: payload.nom,
    };
    Json(utilisateur) // Sérialisé automatiquement en JSON
}

Actix Web

Actix Web a longtemps été le framework de référence pour sa vitesse pure (souvent en tête des benchmarks TechEmpower).

Il utilise son propre runtime optimisé au-dessus de Tokio et repose sur un modèle d’exécution par thread très strict.

  • Macros d’attributs : Utilise des attributs comme #[get("/")] pour lier les fonctions aux routes.
  • État partagé : L’état de l’application est injecté via web::Data.
use actix_web::{get, post, web, App, HttpServer, Responder, HttpResponse};
use serde::Deserialize;

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

#[get("/")]
async fn index() -> impl Responder {
    HttpResponse::Ok().body("Bienvenue sur l'API Actix Web !")
}

#[post("/configuration")]
async fn configurer(form: web::Json<Info>) -> impl Responder {
    format!("Configuration reçue pour le projet : {}", form.projet)
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    // Le serveur instancie une fabrique d'application par thread système
    HttpServer::new(|| {
        App::new()
            .service(index)
            .service(configurer)
    })
    .bind(("127.0.0.1:8080"))?
    .run()
    .await
}

Comparatif

CritèreAxumActix Web
ÉcosystèmeIntégration parfaite avec tokio, tower (middlewares) et hyper.Propre écosystème (actix-rt, actix-net).
Style d’écritureBasé sur les fonctions, les extracteurs et la composition.Basé sur les macros d’attributs et une configuration orientée objet.
Courbe d’apprentissagePlus naturelle si l’on maîtrise déjà Tokio et les types génériques complexes.Plus proche des frameworks traditionnels (comme Express ou Actix dans d’autres langages).
Gestion des erreursRepose sur le système de conversion de types (IntoResponse).Utilise un trait spécifique ResponseError.
PerformanceExcellente, largement suffisante pour l’immense majorité des cas.Légèrement supérieure en performance brute pure sur des micro-benchmarks.