Microservices en Rust : architecture et pratique pour débutants

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : Pourquoi Rust pour les microservices ?

L'architecture microservices est depuis longtemps devenue la norme pour construire des systèmes distribués évolutifs. Habituellement, on choisit Go, Java ou Node.js pour sa mise en œuvre. Cependant, ces dernières années, Rust attire de plus en plus l'attention — un langage de programmation système qui combine les performances du C++ avec la sécurité mémoire. Dans cet article sur pythonlib.ru, nous allons voir comment créer des microservices en Rust, quelles bibliothèques utiliser et comment organiser l'architecture.

Rust est idéal pour les microservices grâce à :

  • L'absence de ramasse-miettes (faible latence et consommation mémoire prévisible) ;
  • La gestion sécurisée de la mémoire à la compilation ;
  • L'excellent support de l'asynchrone via l'écosystème Tokio ;
  • La petite taille du binaire final (idéal pour la conteneurisation).


Architecture d'un microservice en Rust

Un microservice typique en Rust se compose de plusieurs couches :

  • Serveur HTTP (généralement basé sur actix-web ou axum) ;
  • Logique métier (fonctions Rust pures) ;
  • Couche de données (interaction avec la base de données via sqlx ou diesel) ;
  • Runtime asynchrone (Tokio) ;
  • Sérialisation (le plus souvent serde pour le JSON).

Examinons l'architecture de base à l'aide d'un exemple simple de service de gestion d'utilisateurs.



1. Configuration du projet et dépendances

Créez un nouveau projet Cargo et ajoutez les dépendances dans Cargo.toml :

[package]name = "user-service"version = "0.1.0"edition = "2021"

[dependencies]actix-web = "4"serde = { version = "1", features = ["derive"] }serde_json = "1"tokio = { version = "1", features = ["full"] }sqlx = { version = "0.7", features = ["runtime-tokio", "postgres"] }dotenv = "0.15"


2. Création de la structure de base du serveur

Définissons les modèles de données et lançons le serveur HTTP :

use actix_web::{web, App, HttpServer, Responder};use serde::{Deserialize, Serialize};

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

// Stockage en mémoire pour l'exempleasync fn get_users() -> impl Responder { let users = vec![ User { id: 1, name: "Alice".into(), email: "alice@example.com".into() }, User { id: 2, name: "Bob".into(), email: "bob@example.com".into() }, ]; web::Json(users)}

#[actix_web::main]async fn main() -> std::io::Result<()> { println!("Starting user-service on http://127.0.0.1:8080");

HttpServer::new(|| { App::new() .route("/users", web::get().to(get_users)) }) .bind("127.0.0.1:8080")? .run() .await}

Ceci est un microservice minimal. Notez que #[actix_web::main] est une macro qui lance le runtime asynchrone Tokio.



3. Interaction asynchrone avec la base de données

Un vrai microservice doit persister les données. Utilisons sqlx pour PostgreSQL. Créons un fichier .env avec l'URL de connexion :

DATABASE_URL=postgres://user:password@localhost/users_db

Écrivons maintenant une fonction pour récupérer les utilisateurs depuis la base de données :

use sqlx::PgPool;

async fn get_users_from_db(pool: web::Data<PgPool>) -> impl Responder { // Exécute la requête SQL et mappe le résultat dans la structure User let users: Vec<User> = sqlx::query_as::<_, User>("SELECT id, name, email FROM users") .fetch_all(pool.get_ref()) .await .unwrap_or_default();

web::Json(users)}

#[actix_web::main]async fn main() -> std::io::Result<()> { dotenv::dotenv().ok(); let database_url = std::env::va

Blogs

Book Recommendations