Envoyer un email transactionnel en Rust avec Tokio

Le SDK Rust Spore associe des modèles Serde générés à un client Reqwest asynchrone. Votre service garde un flux explicite et typé ; Spore prend en charge la signature, la file d’envoi, les retries et les bounces.

Ce que nous allons construire

Un envoi asynchrone sous Tokio, authentifié par variable d’environnement et protégé contre les doublons par une clé d’idempotence stable.

1. Installer le crate

cargo add spore-email
cargo add tokio --features macros,rt-multi-thread
export SPORE_API_KEY="spore_api_key_here"

Le crate utilise Rustls par défaut : aucune dépendance OpenSSL système n’est nécessaire pour ce chemin standard.

2. Configurer le client

use spore_email::apis::configuration::Configuration;
 
fn spore_configuration() -> Result<Configuration, std::env::VarError> {
    let mut configuration = Configuration::new();
    configuration.bearer_access_token = Some(std::env::var("SPORE_API_KEY")?);
    Ok(configuration)
}

3. Envoyer dans une tâche Tokio

use spore_email::{
    apis::messaging_api::{send_email, SendEmailParams},
    models::SendEmailSendEmailRequest,
};
 
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let configuration = spore_configuration()?;
 
    let mut message = SendEmailSendEmailRequest::new();
    message.from = Some("hello@votredomaine.fr".into());
    message.to = Some(vec!["alex@example.com".into()]);
    message.subject = Some("Bienvenue".into());
    message.html = Some("<p>Votre compte est prêt.</p>".into());
 
    let result = send_email(&configuration, SendEmailParams {
        request: message,
        idempotency_key: Some("welcome:user_42".into()),
    }).await?;
 
    println!("{}", result.message_id.unwrap_or_default());
    Ok(())
}

Le compilateur vérifie la forme des modèles et les types de retour. La réponse reste asynchrone au niveau métier : 202 signifie que Spore a mis le message en file, pas que la boîte du destinataire l’a déjà reçu.

4. Retenter sans doublon

Conservez welcome:user_42 dans votre job ou dérivez la clé d’un identifiant de commande. Une nouvelle clé à chaque tentative contournerait l’idempotence. Avec une clé stable, une reprise après coupure réseau retourne la réponse initiale sans nouvel envoi.

5. Choisir la stratégie TLS

Rustls est le choix par défaut et simplifie les images de conteneur. Si votre environnement impose le magasin de certificats natif :

spore-email = { version = "0.1", default-features = false, features = ["native-tls"] }

Continuez avec la documentation du SDK Rust ou la référence de sendEmail.