Introduction : Pourquoi Rust est le langage idéal pour le Serverless
L'architecture serverless est devenue la norme pour les applications cloud modernes. Cependant, les langages classiques (Python, Node.js) souffrent souvent d'un démarrage à froid lent et d'une consommation mémoire élevée. Rust résout ces problèmes : ses binaires compilés se lancent en quelques millisecondes, et la consommation mémoire est minimale. Dans cet article, nous allons voir comment créer, déployer et optimiser des fonctions AWS Lambda en Rust — de la configuration de l'environnement au déploiement en production.
1. Configuration de l'environnement et des outils
Installation de Rust et Cargo Lambda
Pour travailler avec AWS Lambda en Rust, vous aurez besoin de :
- Rust (installation via
rustup) - Cargo Lambda — l'outil officiel pour la compilation et le déploiement
- AWS CLI avec des credentials configurés
# Installation de Rustcurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Installation de Cargo Lambdacargo install cargo-lambda
# Vérificationcargo lambda --versionCréation d'un nouveau projet
Cargo Lambda génère automatiquement un modèle avec le support de Lambda Runtime API :
cargo lambda new my-rust-lambdacd my-rust-lambdaLa structure du projet inclut un fichier Cargo.toml avec les dépendances lambda_runtime et serde, ainsi qu'un fichier src/main.rs avec une fonction de gestionnaire de base.
2. Écriture de votre première fonction Serverless en Rust
Structure de base du gestionnaire
Examinons une fonction Lambda simple qui reçoit un JSON avec un nom et renvoie un message de bienvenue :
use lambda_runtime::{service_fn, LambdaEvent, Error};use serde::{Deserialize, Serialize};
#[derive(Deserialize)]struct Request { name: String,}
#[derive(Serialize)]struct Response { message: String, request_id: String,}
async fn handler(event: LambdaEvent<Request>) -> Result<Response, Error> { let req = event.payload; let resp = Response { message: format!("Bonjour, {} ! Tu es sur Rust !", req.name), request_id: event.context.request_id, }; Ok(resp)}
#[tokio::main]async fn main() -> Result<(), Error> { lambda_runtime::run(service_fn(handler)).await}Points clés :
service_fnencapsule la fonction asynchrone dans un gestionnaireLambdaEventcontient le payload et le contexte (request_id, deadline, etc.)- Sérialisation/désérialisation via
serde
Test local
Avant le déploiement, testons la fonction localement :
cargo lambda watch# Dans un autre terminal :cargo lambda invoke --data-ascii '{"name": "Monde"}'Vous devriez obtenir la réponse : {"message":"Bonjour, Monde ! Tu es sur Rust !","request_id":"..."}
3. Travail avec les services AWS (S3, DynamoDB)
Intégration avec S3 via AWS SDK
Ajoutons dans Cargo.toml :
[dependencies]aws-sdk-s3 = "1.0"aws-config = "1.0"Exemple de fonction qui lit un objet depuis S3 :
use aws_sdk_s3::Client;
async fn handler(event: LambdaEvent<Request>) -> Result<Response, Error> { let config = aws_config::load_from_env().await; let s3_client = Client::new(&config);
let bucket = "my-bucket"; let key = &event.payload.name;
let object = s3_client .get_object() .bucket(bucket) .key(key) .send() .await?;
let body = object.body.collect().await?; let content = String::from_utf8(body.to_vec())?;
Ok(Response { message: format!("Contenu du fichier : {}", content), request_id: event.context.request_id, })}En