Introduction : Pourquoi Rust pour les API REST ?
Rust est un langage de programmation système moderne qui combine les performances du C/C++ et la sécurité mémoire. Ces dernières années, il est activement utilisé pour créer des services web et des API REST à forte charge. Grâce au framework Actix-web, écrire une API REST complète en Rust peut se faire en seulement 30 minutes, même si vous commencez tout juste à apprendre le langage.
Dans cet article, nous allons créer une API REST simple mais fonctionnelle pour gérer une liste de tâches (Todo List). Vous apprendrez à :
- Configurer un projet Rust avec Actix-web
- Implémenter les opérations CRUD (Create, Read, Update, Delete)
- Travailler avec les requêtes et réponses JSON
- Utiliser le routage et les gestionnaires
Prêts ? C'est parti !
Étape 1 : Configuration du projet et installation des dépendances
Pour commencer, assurez-vous d'avoir Rust installé. Sinon, exécutez la commande :
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shCréez un nouveau projet :
cargo new rust_todo_apicd rust_todo_apiOuvrez Cargo.toml et ajoutez les dépendances suivantes :
[dependencies]actix-web = "4"serde = { version = "1.0", features = ["derive"] }serde_json = "1.0"tokio = { version = "1", features = ["full"] }Ici :
- actix-web — un puissant framework web asynchrone
- serde — pour la sérialisation/désérialisation JSON
- tokio — le runtime asynchrone (Actix-web l'utilise en interne)
Exécutez cargo build pour télécharger et compiler les dépendances. Cela prendra 2 à 3 minutes.
Étape 2 : Création du modèle de données et du stockage
Dans ce projet, nous n'utiliserons pas de base de données — par souci de simplicité, nous utiliserons un vecteur en mémoire. Créons une structure pour la tâche.
Ouvrez src/main.rs et écrivez le code suivant :
use actix_web::{web, App, HttpServer, HttpResponse, middleware};use serde::{Deserialize, Serialize};use std::sync::Mutex;
// Modèle de tâche#[derive(Serialize, Deserialize, Clone)]struct Task { id: u32, title: String, completed: bool,}
// Stockage des tâches (thread-safe)struct AppState { tasks: Mutex<Vec<Task>>,}Explications :
- #[derive(Serialize, Deserialize)] — génère automatiquement les méthodes pour travailler avec JSON
- Mutex — garantit un accès sécurisé aux données depuis plusieurs threads
- AppState — sera stocké dans l'état de l'application
Étape 3 : Implémentation des gestionnaires CRUD
Ajoutons maintenant les fonctions gestionnaires pour chaque méthode HTTP. Insérez le code suivant après la déclaration des structures :
// Obtenir toutes les tâchesasync fn get_tasks(data: web::Data<AppState>) -> HttpResponse { let tasks = data.tasks.lock().unwrap(); HttpResponse::Ok().json(tasks.clone())}
// Créer une nouvelle tâcheasync fn create_task(data: web::Data<AppState>, body: web::Json<Task>) -> HttpResponse { let mut tasks = data.tasks.lock().unwrap(); let new_id = tasks.len() as u32 + 1; let task = Task { id: new_id, title: body.title.clone(), completed: body.completed, }; tasks.push(task.clone()); HttpResponse::Created().json(task)}
// Mettre à jour une tâcheasync fn update_task( data: web::Data<AppState>, path: web::Path<u32>, body: web::Json<Task>,) -> HttpResponse { let mut tasks = data.tasks.lock().unwrap(); let id = path.into_inner(); if let Some(task) = tasks.iter_mut().find(|t| t.id == id) { task.title = body.title.clone(); task.completed = body.completed; HttpRespons