Introduction : Pourquoi Rust et les bases de données forment une paire idéale
Rust est un langage de programmation système moderne qui gagne en popularité grâce à ses performances, sa sécurité mémoire et son coût d'abstraction nul. De nombreux développeurs venant du monde Python, JavaScript ou Go se demandent : comment travailler avec les bases de données en Rust ? La réponse est simple : Rust fournit des pilotes puissants et sécurisés pour travailler à la fois avec des bases de données relationnelles (PostgreSQL) et orientées documents (MongoDB).
Dans cet article, nous aborderons les bases du travail avec PostgreSQL et MongoDB en Rust. Vous apprendrez à configurer un projet, à vous connecter aux bases de données et à effectuer les opérations CRUD de base. L'article est destiné aux débutants, nous utiliserons donc des exemples simples et compréhensibles.
1. Configuration du projet et installation des dépendances
Avant de commencer, assurez-vous d'avoir installé Rust et Cargo. Créez un nouveau projet :
cargo new rust_db_examplecd rust_db_exampleOuvrez le fichier Cargo.toml et ajoutez les dépendances nécessaires. Pour travailler avec PostgreSQL, nous utiliserons la crate tokio-postgres (pilote asynchrone) et serde pour la sérialisation des données. Pour MongoDB, le pilote officiel mongodb.
[dependencies]tokio = { version = "1", features = ["full"] }tokio-postgres = "0.7"serde = { version = "1", features = ["derive"] }serde_json = "1"mongodb = "2.8"Notez que nous utilisons tokio comme runtime asynchrone, car les deux pilotes fonctionnent de manière asynchrone. C'est une pratique courante pour les applications Rust modernes.
2. Travailler avec PostgreSQL en Rust
PostgreSQL est une base de données relationnelle puissante. Pour travailler avec elle en Rust, nous utiliserons la crate tokio-postgres. Elle fournit une interface asynchrone pour exécuter des requêtes SQL.
2.1 Connexion à la base de données
Créons une fonction pour se connecter à une base de données PostgreSQL locale. Assurez-vous que votre serveur PostgreSQL est en cours d'exécution et qu'une base de données (par exemple, test_db) a été créée :
use tokio_postgres::{NoTls, Error};
#[tokio::main]async fn main() -> Result<(), Error> { // Chaîne de connexion : postgresql://utilisateur:motdepasse@localhost/nombdd let (client, connection) = tokio_postgres::connect( "host=localhost user=postgres dbname=test_db", NoTls, ).await?;
// Lancer la connexion en arrière-plan tokio::spawn(async move { if let Err(e) = connection.await { eprintln!("Erreur de connexion : {}", e); } });
println!("Connexion à PostgreSQL établie !"); Ok(())}2.2 Création d'une table et insertion de données
Créons maintenant une table users et insérons quelques enregistrements :
// Création de la tableclient .execute( "CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(150) UNIQUE NOT NULL )", &[], ) .await?;
// Insertion de donnéeslet name = "Alice";let email = "alice@example.com";client .execute( "INSERT INTO users (name, email) VALUES ($1, $2)", &[&name, &email], ) .await?;
println!("Utilisateur {} ajouté !", name);2.3 Lecture et mise à jour des données
Exécutons une requête SELECT et mettons à jour un enregistrement :
// Lecture des donnéeslet rows = client .query("SELECT id, name, email FROM users", &[]) .await?;
for row in rows { let id: i32 = row.get(0); let name: &str = row.get(1); let email: &str = row.get(2); println!("ID : {}, Nom : {}, Email : {}", id, name, email);}
// Mise à jour d'un enregistrementclient .execute( "UPDATE users SET email = $1 WHERE name = $2", &[&"alice_new