Client HTTP en Rust : faire des requêtes correctement
Rust est un langage de programmation système moderne qui combine les performances du C++ et la sécurité mémoire. Lors du développement d'applications web, de microservices ou d'outils en ligne de commande, il est souvent nécessaire d'interagir avec des API externes. Dans cet article, nous allons voir comment créer un client HTTP en Rust en utilisant les crates populaires reqwest et ureq. Vous apprendrez à envoyer des requêtes GET et POST, à gérer les erreurs et à travailler avec JSON.
Pourquoi Rust pour les requêtes HTTP ?
Rust offre des avantages uniques pour le travail en réseau :
- Sécurité mémoire — le compilateur garantit l'absence de fuites et de conditions de concurrence.
- Haute performance — vitesse comparable à C/C++.
- Asynchronisme — prise en charge intégrée de async/await pour un travail efficace avec les I/O.
- Écosystème de crates — des milliers de bibliothèques prêtes à l'emploi, y compris des clients HTTP.
Pour travailler avec HTTP en Rust, il existe deux approches principales : synchrone (bloquante) et asynchrone (non bloquante). Nous allons examiner les deux.
Configuration du projet et choix de la crate
Créons un nouveau projet Rust :
cargo new rust-http-clientcd rust-http-clientOuvrez Cargo.toml et ajoutez les dépendances :
[dependencies]# Pour les requêtes asynchronesreqwest = { version = "0.12", features = ["json"] }tokio = { version = "1", features = ["full"] }
# Pour les requêtes synchrones (alternative)ureq = "2.9"Comparaison des crates :
- reqwest — le client HTTP le plus populaire. Prend en charge l'asynchronisme, JSON, les cookies, les proxys.
- ureq — un client synchrone léger. Idéal pour les scripts simples et les outils CLI.
1. Requête GET avec reqwest (asynchrone)
Commençons par une requête GET asynchrone. Créez le fichier src/main.rs :
use reqwest;use std::error::Error;
#[tokio::main]async fn main() -> Result<(), Box<dyn Error>> { // Envoie une requête GET let response = reqwest::get("https://api.github.com/repos/rust-lang/rust") .await? .text() .await?;
println!("Réponse de l'API GitHub :"); println!("{}", &response[..500]); // Affiche les 500 premiers caractères
Ok(())}Explication :
#[tokio::main]— macro pour lancer le runtime asynchrone Tokio.reqwest::get()— envoie une requête GET et retourne uneResponse..await?— attend la fin de l'opération et gère les erreurs..text()— extrait le corps de la réponse sous forme de chaîne.
Lancez le projet :
cargo runVous verrez la réponse JSON de l'API GitHub.
2. Requête POST avec JSON (reqwest)
Envoyons maintenant une requête POST avec un corps au format JSON :
use reqwest;use serde::{Deserialize, Serialize};use std::error::Error;
#[derive(Serialize, Deserialize, Debug)]struct Post { title: String, body: String, user_id: u32,}
#[derive(Deserialize, Debug)]struct CreatedPost { id: u32, title: String,}
#[tokio::main]async fn main() -> Result<(), Box<dyn Error>> { // Crée un client avec des paramètres let client = reqwest::Client::new();
// Données à envoyer let new_post = Post { title: "Client HTTP en Rust".to_string(), body: "Guide complet pour travailler avec HTTP en Rust".to_string(), user_id: 1, };
// Envoie une requête POST let response = client .post("https://jsonplaceholder.typicode.com/posts") .json(&new_post) .send() .await?;
//
```