

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Création de fonctions Lambda avec Rust
<a name="lambda-rust"></a>

Étant donné que Rust se compile en code natif, vous n’avez pas besoin d’une d’exécution dédiée pour exécuter du code Rust sur Lambda. Utilisez plutôt le [client d'exécution Rust](https://github.com/aws/aws-lambda-rust-runtime) pour créer votre projet localement, puis déployez-le sur Lambda à l'aide d'un environnement d'exécution uniquement pour le système [d'](runtimes-provided.md)exploitation. Lorsque vous utilisez un environnement d'exécution uniquement pour le système d'exploitation, Lambda tient automatiquement le système d'exploitation à jour avec les derniers correctifs.

**Outils et bibliothèques pour Rust**
+ [AWS SDK pour Rust](https://docs.aws.amazon.com/sdk-for-rust/latest/dg/getting-started.html): Le AWS SDK pour Rust permet à Rust APIs d'interagir avec les services d'infrastructure Amazon Web Services.
+  [Client d'exécution Rust pour Lambda](https://github.com/aws/aws-lambda-rust-runtime) : Le client d'exécution Rust facilite l'exécution de fonctions Lambda écrites en Rust.
+ [Cargo Lambda](https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html) : il s'agit d'une extension open source tierce de l'outil de ligne de commande Cargo qui simplifie la création et le déploiement des fonctions Rust Lambda.
+ [Lambda HTTP](https://github.com/aws/aws-lambda-rust-runtime/tree/main/lambda-http) : cette bibliothèque fournit un wrapper pour travailler avec des événements HTTP.
+  [Extension Lambda](https://github.com/aws/aws-lambda-rust-runtime/tree/main/lambda-extension) : cette bibliothèque fournit un support pour écrire des extensions Lambda avec Rust. 
+ [AWS Lambda Événements](https://crates.io/crates/aws_lambda_events) : cette bibliothèque fournit des définitions de type pour les intégrations de sources d'événements courantes.

**Exemples d’applications Lambda pour Rust**
+ [Fonction Lambda de base](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/basic-lambda) : une fonction Rust qui montre comment traiter des événements de base.
+ [Fonction Lambda avec gestion des erreurs](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/basic-error-handling) : une fonction Rust qui montre comment gérer des erreurs Rust personnalisées dans Lambda.
+ [Fonction Lambda avec ressources partagées](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/basic-shared-resource) : un projet Rust qui initialise les ressources partagées avant de créer la fonction Lambda.
+ [Événements HTTP Lambda](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/http-basic-lambda) : une fonction Rust qui gère les événements HTTP.
+ [Événements HTTP Lambda avec en-têtes CORS](https://github.com/aws/aws-lambda-rust-runtime/blob/main//examples/http-cors) : une fonction Rust qui utilise Tower pour injecter des en-têtes CORS.
+ [API REST Lambda](https://github.com/aws/aws-lambda-rust-runtime/tree/main/examples/http-axum-diesel) : une API REST qui utilise Axum et Diesel pour la connexion à une base de données PostgreSQL.
+ [Démo Rust sans serveur](https://github.com/aws-samples/serverless-rust-demo/) : un projet Rust qui montre l'utilisation des bibliothèques Rust de Lambda, de la journalisation, des variables d'environnement et du AWS SDK.
+ [Extension Lambda de base](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/extension-basic) : une extension Rust qui montre comment traiter les événements d’extension de base.
+ [Extension Lambda Logs Amazon Data Firehose](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/extension-logs-kinesis-firehose) : une extension Rust qui montre comment envoyer les journaux Lambda à Firehose.

**Topics**
+ [

# Définir des gestionnaires de fonctions Lambda en Rust
](rust-handler.md)
+ [

# Utilisation de l’objet de contexte Lambda pour récupérer les informations de la fonction Rust
](rust-context.md)
+ [

# Traitement des événements HTTP avec Rust
](rust-http-events.md)
+ [

# Déploiement de fonctions Lambda Rust avec des archives de fichiers .zip
](rust-package.md)
+ [

# Utilisation de couches pour les fonctions Lambda Rust
](rust-layers.md)
+ [

# Journalisation et surveillance des fonctions Lambda Rust
](rust-logging.md)

# Définir des gestionnaires de fonctions Lambda en Rust
<a name="rust-handler"></a>

Le *gestionnaire* de fonction Lambda est la méthode dans votre code de fonction qui traite les événements. Lorsque votre fonction est invoquée, Lambda exécute la méthode du gestionnaire. Votre fonction s’exécute jusqu’à ce que le gestionnaire renvoie une réponse, se ferme ou expire.

Cette page explique comment utiliser les gestionnaires de fonctions Lambda dans Rust, notamment l’initialisation du projet, les conventions de dénomination et les pratiques exemplaires. Cette page inclut également un exemple de fonction Lambda Rust qui collecte des informations relatives à une commande, produit un reçu sous forme de fichier texte et place ce fichier dans un compartiment Amazon Simple Storage Service (S3). Pour plus d’informations sur le déploiement de votre fonction après l’avoir écrite, consultez [Déploiement de fonctions Lambda Rust avec des archives de fichiers .zip](rust-package.md).

**Topics**
+ [

## Configuration de votre projet de gestionnaire Rust
](#rust-handler-setup)
+ [

## Exemple de fonction Lambda Rust
](#rust-example-code)
+ [

## Définitions de classe valides pour les gestionnaires Rust
](#rust-handler-signatures)
+ [

## Convention de nommage du gestionnaire
](#rust-example-naming)
+ [

## Définition et accès à l’objet d’événement d’entrée
](#rust-handler-input)
+ [

## Accès et utilisation de l’objet de contexte Lambda
](#rust-example-context)
+ [

## En utilisant le AWS SDK pour Rust dans votre gestionnaire
](#rust-example-sdk-usage)
+ [

## Accès aux variables d’environnement
](#rust-example-envvars)
+ [

## Utilisation de l’état partagé
](#rust-shared-state)
+ [

## Pratiques exemplaires en matière de code pour les fonctions Lambda Rust
](#rust-best-practices)

## Configuration de votre projet de gestionnaire Rust
<a name="rust-handler-setup"></a>

Lorsque vous utilisez des fonctions Lambda en Rust, le processus consiste à écrire votre code, à le compiler et à déployer les artefacts compilés sur Lambda. Le moyen le plus simple de configurer un projet de gestionnaire Lambda dans Rust est d’utiliser l’[environnement d’exécution AWS Lambda pour Rust](https://github.com/aws/aws-lambda-rust-runtime). Malgré son nom, le AWS Lambda Runtime for Rust n'est pas un environnement d'exécution géré au même sens que dans Lambda pour Python, Java ou Node.js. Au lieu de cela, le AWS Lambda Runtime for Rust est un crate (`lambda_runtime`) qui permet d'écrire des fonctions Lambda dans Rust et de s'interfacer avec l'environnement d'exécution AWS Lambda de celui-ci.

Utilisez la commande suivante pour installer [Cargo Lambda](https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html), une extension open source tierce de l'outil de ligne de commande Cargo qui simplifie la création et le déploiement des fonctions Rust Lambda :

```
cargo install cargo-lambda
```

Après avoir installé `cargo-lambda`, utilisez la commande suivante pour initialiser un nouveau projet de gestionnaire de fonction Lambda :

```
cargo lambda new example-rust
```

Lorsque vous exécutez cette commande, l’interface de ligne de commande (CLI) vous pose quelques questions concernant votre fonction Lambda :
+ **Fonction HTTP** : si vous avez l’intention d’invoquer votre fonction via [API Gateway](services-apigateway.md) ou une [URL de fonction](urls-configuration.md), répondez **Oui**. Dans le cas contraire, répondez **Non**. Dans l’exemple de code de cette page, nous invoquons notre fonction avec un événement JSON personnalisé. Nous répondons donc **Non**.
+ **Type d’événement** : si vous avez l’intention d’utiliser une forme d’événement prédéfinie pour invoquer votre fonction, sélectionnez le type d’événement attendu approprié. Sinon, laissez cette option vide. Dans l’exemple de code de cette page, nous invoquons notre fonction avec un événement JSON personnalisé. Nous laissons donc cette option vide.

Une fois la commande exécutée avec succès, entrez dans le répertoire principal de votre projet :

```
cd example-rust
```

Cette commande génère un fichier `generic_handler.rs` et un fichier `main.rs` dans le répertoire `src`. `generic_handler.rs` peut être utilisé pour personnaliser un gestionnaire d’événements générique. Le fichier `main.rs` contient la logique de votre application principale. Le fichier `Cargo.toml` contient des métadonnées relatives à votre package et répertorie ses dépendances externes.

## Exemple de fonction Lambda Rust
<a name="rust-example-code"></a>

L’exemple de code de fonction Lambda Rust suivant prend en compte les informations relatives à une commande, produit un reçu sous forme de fichier texte et place ce fichier dans un compartiment Amazon S3.

**Example Fonction Lambda `main.rs`**  

```
use aws_sdk_s3::{Client, primitives::ByteStream};
use lambda_runtime::{run, service_fn, Error, LambdaEvent};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::env;

#[derive(Deserialize, Serialize)]
struct Order {
    order_id: String,
    amount: f64,
    item: String,
}

async fn function_handler(event: LambdaEvent<Value>) -> Result<String, Error> {
    let payload = event.payload;

    // Deserialize the incoming event into Order struct
    let order: Order = serde_json::from_value(payload)?;

    let bucket_name = env::var("RECEIPT_BUCKET")
        .map_err(|_| "RECEIPT_BUCKET environment variable is not set")?;

    let receipt_content = format!(
        "OrderID: {}\nAmount: ${:.2}\nItem: {}",
        order.order_id, order.amount, order.item
    );
    let key = format!("receipts/{}.txt", order.order_id);

    let config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
    let s3_client = Client::new(&config);

    upload_receipt_to_s3(&s3_client, &bucket_name, &key, &receipt_content).await?;

    Ok("Success".to_string())
}

async fn upload_receipt_to_s3(
    client: &Client,
    bucket_name: &str,
    key: &str,
    content: &str,
) -> Result<(), Error> {
    client
        .put_object()
        .bucket(bucket_name)
        .key(key)
        .body(ByteStream::from(content.as_bytes().to_vec()))  // Fixed conversion
        .content_type("text/plain")
        .send()
        .await?;

    Ok(())
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    run(service_fn(function_handler)).await
}
```

Ce fichier `main.rs` comprend les sections suivantes :
+ Instructions `use` : utilisez-les pour importer des conteneurs (crates) et méthodes Rust que votre fonction Lambda requiert.
+ `#[derive(Deserialize, Serialize)]` : définissez la forme de l’événement d’entrée attendu dans cette structure Rust.
+ `async fn function_handler(event: LambdaEvent<Value>) -> Result<String, Error>` : il s’agit de la **méthode de gestion principale**, qui contient la logique principale de votre application.
+ `async fn upload_receipt_to_s3 (...)` : il s’agit d’une méthode auxiliaire référencée par la méthode `function_handler` principale.
+ `#[tokio::main]` : il s’agit d’une macro qui marque le point d’entrée d’un programme Rust. Elle met également en place un [environnement d’exécution Tokio](https://docs.rs/tokio/latest/tokio/runtime/index.html), qui permet à votre méthode `main()` d’utiliser `async`/`await` et de s’exécuter de manière asynchrone.
+ `async fn main() -> Result<(), Error>` : la fonction `main()` est le point d’entrée de votre code. À l’intérieur, nous spécifions `function_handler` comme méthode de gestionnaire principal.

### Exemple de fichier Cargo.toml
<a name="rust-cargo-toml"></a>

Le fichier `Cargo.toml` suivant accompagne cette fonction.

```
[package]
name = "example-rust"
version = "0.1.0"
edition = "2024"

[dependencies]
aws-config = "1.5.18"
aws-sdk-s3 = "1.78.0"
lambda_runtime = "0.13.0"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tokio = { version = "1", features = ["full"] }
```

Pour que cette fonction fonctionne correctement, son [rôle d’exécution](lambda-intro-execution-role.md) doit autoriser l’action `s3:PutObject`. Assurez-vous également de définir la variable d’environnement `RECEIPT_BUCKET`. Après une invocation réussie, le compartiment Amazon S3 doit contenir un fichier de reçu.

## Définitions de classe valides pour les gestionnaires Rust
<a name="rust-handler-signatures"></a>

Dans la plupart des cas, les signatures du gestionnaire Lambda que vous définissez dans Rust auront le format suivant :

```
async fn function_handler(event: LambdaEvent<T>) -> Result<U, Error>
```

Pour ce gestionnaire :
+ Le nom de ce gestionnaire est `function_handler`.
+ L’entrée singulière du gestionnaire est un événement, et est de type `LambdaEvent<T>`.
  + `LambdaEvent` est un wrapper qui vient du conteneur (crate) `lambda_runtime`. L’utilisation de ce wrapper vous donne accès à l’objet de contexte, qui inclut des métadonnées spécifiques à Lambda, comme l’ID de demande de l’invocation.
  + `T` est le type d’événement désérialisé. Par exemple, cela peut être `serde_json::Value`, qui permet au gestionnaire d’accepter n’importe quelle entrée JSON générique. Il peut également s’agir d’un type comme `ApiGatewayProxyRequest` si votre fonction attend un type d’entrée spécifique et prédéfini.
+ Le type de retour du gestionnaire est `Result<U, Error>`.
  + `U` est le type de sortie désérialisé. `U` doit implémenter la caractéristique `serde::Serialize` afin que Lambda puisse convertir la valeur de retour en JSON. Par exemple, `U` peut être un type simple comme `String`, `serde_json::Value` ou une structure personnalisée tant qu’il implémente `Serialize`. Lorsque votre code atteint une instruction Ok(U), cela indique une exécution réussie et votre fonction renvoie une valeur de type `U`.
  + Lorsque votre code rencontre une erreur (c'est-à-dire`Err(Error)`), votre fonction enregistre l'erreur dans Amazon CloudWatch et renvoie une réponse d'erreur de type`Error`.

Dans notre exemple, la signature du gestionnaire ressemble à ce qui suit :

```
async fn function_handler(event: LambdaEvent<Value>) -> Result<String, Error>
```

Les autres signatures de gestionnaire valides peuvent présenter les caractéristiques suivantes :
+ Omission du wrapper `LambdaEvent` : si vous omettez `LambdaEvent`, vous perdez l’accès à l’objet de contexte Lambda dans votre fonction. Voici un exemple de ce type de signature :

  ```
  async fn handler(event: serde_json::Value) -> Result<String, Error>
  ```
+ Utilisation du type d’unité comme entrée : pour Rust, vous pouvez utiliser le type d’unité pour représenter une entrée vide. Cela est couramment utilisé pour les fonctions avec des invocations périodiques et planifiées. Voici un exemple de ce type de signature :

  ```
  async fn handler(_: ()) -> Result<Value, Error>
  ```

## Convention de nommage du gestionnaire
<a name="rust-example-naming"></a>

Les gestionnaires Lambda dans Rust n’ont pas de restrictions de dénomination strictes. Bien que vous puissiez utiliser n’importe quel nom pour votre gestionnaire, les noms de fonctions en Rust suivent généralement le format de casse `snake_case`.

Pour les applications plus petites, comme dans cet exemple, vous pouvez utiliser un seul fichier `main.rs` pour contenir l’ensemble de votre code. Pour les projets plus importants, `main.rs` doit contenir le point d’entrée de votre fonction, mais vous pouvez avoir des fichiers supplémentaires pour séparer votre code en modules logiques. Par exemple, vous pouvez avoir la structure de fichiers suivante :

```
/example-rust
│── src/
│   ├── main.rs        # Entry point
│   ├── handler.rs     # Contains main handler
│   ├── services.rs    # [Optional] Back-end service calls
│   ├── models.rs      # [Optional] Data models
│── Cargo.toml
```

## Définition et accès à l’objet d’événement d’entrée
<a name="rust-handler-input"></a>

JSON est le format d’entrée le plus courant et standard pour les fonctions Lambda. Dans cet exemple, la fonction exige une entrée similaire à l’exemple suivant :

```
{
    "order_id": "12345",
    "amount": 199.99,
    "item": "Wireless Headphones"
}
```

En Rust, vous pouvez définir la forme de l’événement d’entrée attendu dans une structure. Dans cet exemple, nous définissons la structure suivante pour représenter un `Order` :

```
#[derive(Deserialize, Serialize)]
struct Order {
    order_id: String,
    amount: f64,
    item: String,
}
```

Cette structure correspond à la forme d’entrée attendue. Dans cet exemple, la macro `#[derive(Deserialize, Serialize)]` génère automatiquement du code pour la sérialisation et la désérialisation. Cela signifie que nous pouvons désérialiser le type JSON d’entrée générique dans notre structure à l’aide de la méthode `serde_json::from_value()`. Ceci est illustré dans les premières lignes du gestionnaire :

```
async fn function_handler(event: LambdaEvent<Value>) -> Result<String, Error> {
    let payload = event.payload;

    // Deserialize the incoming event into Order struct
    let order: Order = serde_json::from_value(payload)?;
    ...
}
```

Vous pouvez ensuite accéder aux champs de l’objet. Par exemple, `order.order_id` récupère la valeur de `order_id` à partir de l’entrée d’origine.

### Types d’événements d’entrée prédéfinis
<a name="rust-input-event-types"></a>

De nombreux types d’événements d’entrée prédéfinis sont disponibles dans le conteneur (crate) `aws_lambda_events`. Par exemple, si vous avez l’intention d’invoquer votre fonction avec API Gateway, y compris l’importation suivante :

```
use aws_lambda_events::event::apigw::ApiGatewayProxyRequest;
```

assurez-vous que votre gestionnaire principal utilise la signature suivante :

```
async fn handler(event: LambdaEvent<ApiGatewayProxyRequest>) -> Result<String, Error> {
    let body = event.payload.body.unwrap_or_default();
    ...
}
```

Reportez-vous au [conteneur aws\$1lambda\$1events](https://crates.io/crates/aws_lambda_events) pour plus d’informations sur les autres types d’événements d’entrée prédéfinis.

## Accès et utilisation de l’objet de contexte Lambda
<a name="rust-example-context"></a>

L’[objet de contexte](rust-context.md) Lambda contient des informations sur l’invocation, la fonction et l’environnement d’exécution. En Rust, le wrapper `LambdaEvent` inclut l’objet de contexte. Par exemple, vous pouvez utiliser l’objet de contexte pour récupérer l’ID de demande de l’invocation en cours à l’aide du code suivant :

```
async fn function_handler(event: LambdaEvent<Value>) -> Result<String, Error> {
    let request_id = event.context.request_id;
    ...
}
```

Pour plus d’informations sur la copie d’objets, consultez [Utilisation de l’objet de contexte Lambda pour récupérer les informations de la fonction Rust](rust-context.md).

## En utilisant le AWS SDK pour Rust dans votre gestionnaire
<a name="rust-example-sdk-usage"></a>

Vous utiliserez souvent les fonctions Lambda pour interagir avec d'autres AWS ressources ou pour les mettre à jour. Le moyen le plus simple d’interagir avec ces ressources est d’utiliser [AWS SDK pour Rust](https://docs.aws.amazon.com/sdk-for-rust/latest/dg/welcome.html).

Pour ajouter des dépendances du SDK à votre fonction, ajoutez-les dans votre fichier `Cargo.toml`. Nous vous recommandons de n’ajouter que les bibliothèques dont vous avez besoin pour votre fonction. Dans l’exemple de code précédent, nous avons utilisé `aws_sdk_s3::Client`. Dans le fichier `Cargo.toml`, vous pouvez ajouter cette dépendance en ajoutant la ligne suivante sous la section `[dependencies]` :

```
aws-sdk-s3 = "1.78.0"
```

**Note**  
La version n’est peut-être pas la plus récente. Choisissez la version adéquate pour votre application.

Importez ensuite les dépendances directement dans votre code :

```
use aws_sdk_s3::{Client, primitives::ByteStream};
```

L’exemple de code initialise ensuite un client Amazon S3 comme suit :

```
let config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
let s3_client = Client::new(&config);
```

Après avoir initialisé votre client SDK, vous pouvez l'utiliser pour interagir avec d'autres AWS services. L’exemple de code appelle l’API `PutObject` Amazon S3 dans la fonction d’assistance `upload_receipt_to_s3`.

## Accès aux variables d’environnement
<a name="rust-example-envvars"></a>

Dans le code de votre gestionnaire, vous pouvez référencer n’importe quelle [variable d’environnement](configuration-envvars.md) à l’aide de la méthode `env::var`. Dans cet exemple, nous référençons la variable d’environnement `RECEIPT_BUCKET` définie à l’aide de la ligne de code suivante :

```
let bucket_name = env::var("RECEIPT_BUCKET")
    .map_err(|_| "RECEIPT_BUCKET environment variable is not set")?;
```

## Utilisation de l’état partagé
<a name="rust-shared-state"></a>

Vous pouvez déclarer des variables partagées indépendantes du code du gestionnaire de votre fonction Lambda. Ces variables peuvent vous aider à charger des informations d’état pendant le [Phase d’initialisation](lambda-runtime-environment.md#runtimes-lifecycle-ib), avant que votre fonction ne reçoive des événements. Par exemple, vous pouvez modifier le code de cette page pour utiliser l’état partagé lors de l’initialisation du client Amazon S3 en mettant à jour la fonction `main` et la signature du gestionnaire :

```
async fn function_handler(client: &Client, event: LambdaEvent<Value>) -> Result<String, Error> {
    ...
    upload_receipt_to_s3(client, &bucket_name, &key, &receipt_content).await?;
    ...
}

...
      
#[tokio::main]
async fn main() -> Result<(), Error> {
    let shared_config = aws_config::from_env().load().await;
    let client = Client::new(&shared_config);
    let shared_client = &client;
    lambda_runtime::run(service_fn(move |event: LambdaEvent<Request>| async move {
        handler(&shared_client, event).await
    }))
    .await
```

## Pratiques exemplaires en matière de code pour les fonctions Lambda Rust
<a name="rust-best-practices"></a>

Respectez les directives de la liste suivante pour utiliser les pratiques exemplaires de codage lors de la création de vos fonctions Lambda :
+ **Séparez le gestionnaire Lambda de votre logique principale.** Cela vous permet de créer une fonction testable plus unitaire.
+ **Réduisez la complexité de vos dépendances.** Privilégiez les infrastructures plus simples qui se chargent rapidement au démarrage de l’[environnement d’exécution](lambda-runtime-environment.md).
+ **Réduisez la taille de votre package de déploiement selon ses besoins d’exécution. ** Cela contribue à réduire le temps nécessaire au téléchargement et à la décompression de votre package de déploiement avant l'invocation.

**Tirez parti de la réutilisation de l’environnement d’exécution pour améliorer les performances de votre fonction**. Initialisez les clients SDK et les connexions à la base de données en dehors du gestionnaire de fonctions et mettez en cache les actifs statiques localement dans le répertoire `/tmp`. Les invocations ultérieures traitées par la même instance de votre fonction peuvent réutiliser ces ressources. Cela permet d’économiser des coûts, tout en réduisant le temps d’exécution de la fonction.

Pour éviter des éventuelles fuites de données entre les invocations, n’utilisez pas l’environnement d’exécution pour stocker des données utilisateur, des événements ou d’autres informations ayant un impact sur la sécurité. Si votre fonction repose sur un état réversible qui ne peut pas être stocké en mémoire dans le gestionnaire, envisagez de créer une fonction distincte ou des versions distinctes d’une fonction pour chaque utilisateur.

**Utilisez une directive keep-alive pour maintenir les connexions persistantes.** Lambda purge les connexions inactives au fil du temps. Si vous tentez de réutiliser une connexion inactive lorsque vous invoquez une fonction, cela entraîne une erreur de connexion. Pour maintenir votre connexion persistante, utilisez la directive Keep-alive associée à votre environnement d’exécution. Pour obtenir un exemple, consultez [Réutilisation des connexions avec Keep-Alive dans Node.js](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html).

**Utilisez des [variables d’environnement](configuration-envvars.md) pour transmettre des paramètres opérationnels à votre fonction.** Par exemple, si vous écrivez dans un compartiment Amazon S3 au lieu de coder en dur le nom du compartiment dans lequel vous écrivez, configurez le nom du compartiment comme variable d’environnement.

**Évitez d’utiliser des invocations récursives** dans votre fonction Lambda, lorsque la fonction s’invoque elle-même ou démarre un processus susceptible de l’invoquer à nouveau. Cela peut entraîner un volume involontaire d’invocations de fonction et des coûts accrus. Si vous constatez un volume involontaire d’invocations, définissez immédiatement la simultanéité réservée à la fonction sur `0` afin de limiter toutes les invocations de la fonction, pendant que vous mettez à jour le code.

**N'utilisez pas de code non documenté ni public APIs dans votre code** de fonction Lambda. Pour les AWS Lambda environnements d'exécution gérés, Lambda applique régulièrement des mises à jour de sécurité et fonctionnelles aux applications internes de Lambda. APIs Ces mises à jour internes de l'API peuvent être rétroincompatibles, ce qui peut entraîner des conséquences imprévues, telles que des échecs d'invocation si votre fonction dépend de ces mises à jour non publiques. APIs Consultez [la référence de l'API](https://docs.aws.amazon.com/lambda/latest/api/welcome.html) pour obtenir une liste des API accessibles au public APIs.

**Écriture du code idempotent.** L’écriture de code idempotent pour vos fonctions garantit ne gestion identique des événements dupliqués. Votre code doit valider correctement les événements et gérer correctement les événements dupliqués. Pour de plus amples informations, veuillez consulter[Comment faire en sorte que ma fonction Lambda soit idempotente ?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/).

# Utilisation de l’objet de contexte Lambda pour récupérer les informations de la fonction Rust
<a name="rust-context"></a>

Lorsque Lambda exécute votre fonction, il ajoute un objet de contexte à LambdaEvent celui que le [gestionnaire](rust-handler.md) reçoit. Cet objet fournit les propriétés avec des informations sur l’appel, la fonction et l’environnement d’exécution.

**Propriétés du contexte**
+  `request_id`: ID de AWS demande généré par le service Lambda. 
+  `deadline` : le délai d’exécution de l’invocation en cours en millisecondes.
+  `invoked_function_arn` : l’Amazon Resource Name (ARN) de la fonction Lambda en cours d’invocation.
+  `xray_trace_id`: ID de AWS X-Ray trace pour l'appel en cours. 
+  `client_content`: objet de contexte client envoyé par le SDK AWS mobile. Ce champ est vide sauf si la fonction est invoquée à l'aide d'un SDK AWS mobile. 
+  `identity` : l’identité Amazon Cognito qui a invoqué la fonction. Ce champ est vide sauf si la demande d'invocation adressée au APIs Lambda a été faite à l' AWS aide d'informations d'identification émises par les groupes d'identités Amazon Cognito.
+  `env_config` : la configuration de la fonction Lambda à partir des variables d’environnement locales. Cette propriété comprend des informations telles que le nom de la fonction, l’allocation de mémoire, la version et les flux de journaux.

## Accès aux informations du contexte d’appel
<a name="rust-context-invoke"></a>

Les fonctions Lambda ont accès aux métadonnées sur leur environnement et la demande d’appel. L’objet `LambaEvent` que votre gestionnaire de fonction reçoit comprend les métadonnées `context` :

```
use lambda_runtime::{service_fn, LambdaEvent, Error};
use serde_json::{json, Value};

async fn handler(event: LambdaEvent<Value>) -> Result<Value, Error> {
    let invoked_function_arn = event.context.invoked_function_arn;
    Ok(json!({ "message": format!("Hello, this is function {invoked_function_arn}!") }))
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    lambda_runtime::run(service_fn(handler)).await
}
```

# Traitement des événements HTTP avec Rust
<a name="rust-http-events"></a>

Amazon API Gateway APIs, les équilibreurs de charge d'application et la URLs fonction [Lambda](urls-configuration.md) peuvent envoyer des événements HTTP à Lambda. Vous pouvez utiliser la caisse [aws\$1lambda\$1events](https://crates.io/crates/aws_lambda_events) de crates.io pour traiter les événements provenant de ces sources.

**Example – Gestion de la demande de proxy API Gateway**  
Notez ce qui suit :  
+ `use aws_lambda_events::apigw::{ApiGatewayProxyRequest, ApiGatewayProxyResponse}` : la caisse [aws\$1lambda\$1events](https://crates.io/crates/aws-lambda-events) inclut de nombreux événements Lambda. Pour réduire le temps de compilation, utilisez les drapeaux de fonction pour activer les événements dont vous avez besoin. Exemple: `aws_lambda_events = { version = "0.8.3", default-features = false, features = ["apigw"] }`.
+ `use http::HeaderMap` : cette importation nécessite d’ajouter la caisse [http](https://crates.io/crates/http) à vos dépendances.

```
use aws_lambda_events::apigw::{ApiGatewayProxyRequest, ApiGatewayProxyResponse};
use http::HeaderMap;
use lambda_runtime::{service_fn, Error, LambdaEvent};

async fn handler(
    _event: LambdaEvent<ApiGatewayProxyRequest>,
) -> Result<ApiGatewayProxyResponse, Error> {
    let mut headers = HeaderMap::new();
    headers.insert("content-type", "text/html".parse().unwrap());
    let resp = ApiGatewayProxyResponse {
        status_code: 200,
        multi_value_headers: headers.clone(),
        is_base64_encoded: false,
        body: Some("Hello AWS Lambda HTTP request".into()),
        headers,
    };
    Ok(resp)
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    lambda_runtime::run(service_fn(handler)).await
}
```

Le [client d’exécution Rust pour Lambda](https://github.com/aws/aws-lambda-rust-runtime) fournit également une abstraction sur ces types d’événements qui vous permet de travailler avec les types HTTP natifs, quel que soit le service qui envoie les événements. Le code suivant est équivalent à l'exemple précédent et fonctionne immédiatement avec la fonction Lambda URLs, les équilibreurs de charge d'application et l'API Gateway.

**Note**  
À la base, la caisse [lambda\$1http](https://crates.io/crates/lambda_http) utilise la caisse [lambda\$1runtime](https://crates.io/crates/lambda_runtime). Vous n’avez pas besoin d’importer `lambda_runtime` séparément.

**Example – Gestion des requêtes HTTP**  

```
use lambda_http::{service_fn, Error, IntoResponse, Request, RequestExt, Response};

async fn handler(event: Request) -> Result<impl IntoResponse, Error> {
    let resp = Response::builder()
        .status(200)
        .header("content-type", "text/html")
        .body("Hello AWS Lambda HTTP request")
        .map_err(Box::new)?;
    Ok(resp)
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    lambda_http::run(service_fn(handler)).await
}
```

Pour un autre exemple d'utilisation`lambda_http`, consultez l'exemple de [code http-axum sur le AWS référentiel](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/http-axum/src/main.rs) Labs. GitHub 

**Exemples d’événements HTTP Lambda pour Rust**
+ [Événements HTTP Lambda](https://github.com/aws/aws-lambda-rust-runtime/tree/main/examples/http-basic-lambda) : une fonction Rust qui gère les événements HTTP.
+ [Événements HTTP Lambda avec en-têtes CORS](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/http-cors) : une fonction Rust qui utilise Tower pour injecter des en-têtes CORS.
+ [Événements HTTP Lambda avec ressources partagées](https://github.com/aws/aws-lambda-rust-runtime/tree/main/examples/basic-shared-resource) : une fonction Rust qui utilise des ressources partagées initialisées avant la création du gestionnaire de fonction.

# Déploiement de fonctions Lambda Rust avec des archives de fichiers .zip
<a name="rust-package"></a>

Cette page décrit comment compiler votre fonction Rust, puis déployer le binaire compilé à l' AWS Lambda aide de [Cargo Lambda](https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html). Il montre également comment déployer le binaire compilé à l'aide de la CLI AWS Command Line Interface et de la AWS Serverless Application Model CLI.

**Topics**
+ [

## Conditions préalables
](#rust-package-prerequisites)
+ [

## Création de fonctions Rust sur macOS, Windows ou Linux
](#rust-package-build)
+ [

## Déploiement du binaire de la fonction Rust avec Cargo Lambda
](#rust-deploy-cargo)
+ [

## Invocation de votre fonction Rust avec Cargo Lambda
](#rust-invoke-function)

## Conditions préalables
<a name="rust-package-prerequisites"></a>
+ [Rust](https://www.rust-lang.org/tools/install)
+ [AWS CLI version 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)

## Création de fonctions Rust sur macOS, Windows ou Linux
<a name="rust-package-build"></a>

Les étapes suivantes montrent comment créer le projet de votre première fonction Lambda avec Rust et le compiler avec Cargo [Lambda](https://www.cargo-lambda.info/), une extension open source tierce de l'outil de ligne de commande Cargo qui simplifie la création et le déploiement des fonctions Rust Lambda.

1. Installez [Cargo Lambda](https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html), une extension open source tierce de l'outil de ligne de commande Cargo qui simplifie la création et le déploiement des fonctions Rust Lambda :

   ```
   cargo install cargo-lambda
   ```

   Pour les autres options d'installation, consultez la section [Installation](https://www.cargo-lambda.info/guide/installation.html) dans la documentation de Cargo Lambda.

1. Créez la structure du package. Cette commande crée un code de fonction de base dans `src/main.rs`. Vous pouvez utiliser ce code pour le tester ou le remplacer par le vôtre.

   ```
   cargo lambda new my-function
   ```

1. À l’intérieur du répertoire racine du package, exécutez la sous-commande [build](https://www.cargo-lambda.info/commands/build.html) pour compiler le code de votre fonction.

   ```
   cargo lambda build --release
   ```

   (Facultatif) Si vous souhaitez utiliser AWS Graviton2 sur Lambda, ajoutez l'`--arm64`indicateur pour compiler votre code pour ARM. CPUs

   ```
   cargo lambda build --release --arm64
   ```

1. Avant de déployer votre fonction Rust, configurez les AWS informations d'identification sur votre machine.

   ```
   aws configure
   ```

## Déploiement du binaire de la fonction Rust avec Cargo Lambda
<a name="rust-deploy-cargo"></a>

Utilisez la sous-commande [deploy](https://www.cargo-lambda.info/commands/deploy.html) pour déployer le binaire compilé vers Lambda. Cette commande crée un [rôle d’exécution](lambda-intro-execution-role.md), puis la fonction Lambda. Pour spécifier un rôle d’exécution existant, utilisez l’[indicateur --iam-role](https://www.cargo-lambda.info/commands/deploy.html#iam-roles).

```
cargo lambda deploy my-function
```

### Déployer le binaire de votre fonction Rust avec le AWS CLI
<a name="rust-deploy-aws-cli"></a>

Vous pouvez également déployer votre binaire avec le AWS CLI.

1. Utilisez la sous-commande [build](https://www.cargo-lambda.info/commands/build.html) pour créer le package de déploiement .zip.

   ```
   cargo lambda build --release --output-format zip
   ```

1. Pour déployer le package .zip vers Lambda, exécutez la commande [create-function](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-function.html).
   + Pour `--runtime`, spécifiez `provided.al2023`. Il s’agit d’un [environnement d’exécution réservé au système d’exploitation](runtimes-provided.md). Les environnements d’exécution réservés au système d’exploitation sont utilisés pour déployer des fichiers binaires compilés et des environnements d’exécution personnalisés sur Lambda.
   + Pour `--role`, spécifiez l’ARN du [rôle d’exécution](lambda-intro-execution-role.md).

   ```
   aws lambda create-function \
        --function-name my-function \
        --runtime provided.al2023 \
        --role arn:aws:iam::111122223333:role/lambda-role \
        --handler rust.handler \
        --zip-file fileb://target/lambda/my-function/bootstrap.zip
   ```

### Déploiement de votre fonction binaire Rust avec la AWS SAM CLI
<a name="rust-deploy-sam-cli"></a>

Vous pouvez également déployer votre binaire à l'aide de la AWS SAM CLI.

1. Créez un AWS SAM modèle avec la définition de la ressource et de la propriété. Pour `Runtime`, spécifiez `provided.al2023`. Il s’agit d’un [environnement d’exécution réservé au système d’exploitation](runtimes-provided.md). Les environnements d’exécution réservés au système d’exploitation sont utilisés pour déployer des fichiers binaires compilés et des environnements d’exécution personnalisés sur Lambda.

   Pour plus d'informations sur le déploiement de fonctions Lambda à l'aide de fonctions Lambda AWS SAM, consultez [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)le manuel du *AWS Serverless Application Model développeur*.  
**Example Définition des ressources et des propriétés SAM pour un binaire Rust**  

   ```
   AWSTemplateFormatVersion: '2010-09-09'
   Transform: AWS::Serverless-2016-10-31
   Description: SAM template for Rust binaries
   Resources:
     RustFunction:
       Type: AWS::Serverless::Function 
       Properties:
         CodeUri: target/lambda/my-function/
         Handler: rust.handler
         Runtime: provided.al2023
   Outputs:
     RustFunction:
       Description: "Lambda Function ARN"
       Value: !GetAtt RustFunction.Arn
   ```

1. Utilisez la sous-commande [build](https://www.cargo-lambda.info/commands/build.html) pour compiler la fonction.

   ```
   cargo lambda build --release
   ```

1. Utilisez la commande [sam deploy](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-deploy.html) pour déployer la fonction vers Lambda.

   ```
   sam deploy --guided
   ```

*Pour plus d'informations sur la création de fonctions Rust avec la AWS SAM CLI, consultez la section [Création de fonctions Rust Lambda avec Cargo Lambda](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/building-rust.html) dans le manuel du développeur.AWS Serverless Application Model *

## Invocation de votre fonction Rust avec Cargo Lambda
<a name="rust-invoke-function"></a>

Utilisez la sous-commande [invoke](https://www.cargo-lambda.info/commands/invoke.html) pour tester votre fonction avec une charge utile.

```
cargo lambda invoke --remote --data-ascii '{"command": "Hello world"}' my-function
```

### Invoquer votre fonction Rust avec le AWS CLI
<a name="rust-invoke-cli"></a>

Vous pouvez également utiliser le AWS CLI pour appeler la fonction.

```
aws lambda invoke --function-name my-function --cli-binary-format raw-in-base64-out --payload '{"command": "Hello world"}' /tmp/out.txt
```

L'**cli-binary-format**option est obligatoire si vous utilisez AWS CLI la version 2. Pour faire de ce paramètre le paramètre par défaut, exécutez `aws configure set cli-binary-format raw-in-base64-out`. Pour plus d’informations, consultez les [options de ligne de commande globales prises en charge par l’AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) dans le *Guide de l’utilisateur AWS Command Line Interface version 2*.

# Utilisation de couches pour les fonctions Lambda Rust
<a name="rust-layers"></a>

Nous déconseillons d’utiliser des [couches](chapter-layers.md) pour gérer les dépendances des fonctions Lambda écrites en Rust. Cela est dû au fait que les fonctions Lambda en Rust sont compilées en un seul exécutable, que vous fournissez à Lambda lorsque vous déployez votre fonction. Cet exécutable contient votre code de fonction compilé, ainsi que toutes ses dépendances. L’utilisation de couches complique non seulement ce processus, mais entraîne également une augmentation des temps de démarrage à froid, car vos fonctions doivent charger manuellement des assemblages supplémentaires en mémoire pendant la phase d’initialisation.

Pour utiliser des dépendances externes avec vos gestionnaires Rust, incluez-les directement dans votre package de déploiement. Ce faisant, vous simplifiez le processus de déploiement et profitez des optimisations du compilateur Rust intégré. Pour un exemple d’importation et d’utilisation d’une dépendance telle que le kit SDK AWS pour Rust dans votre fonction, consultez [Définir des gestionnaires de fonctions Lambda en Rust](rust-handler.md).

# Journalisation et surveillance des fonctions Lambda Rust
<a name="rust-logging"></a>

AWS Lambda surveille automatiquement les fonctions Lambda en votre nom et envoie les journaux à Amazon. CloudWatch Votre fonction Lambda est fournie avec un groupe de CloudWatch journaux Logs et un flux de journaux pour chaque instance de votre fonction. L’environnement d’exécution Lambda envoie des informations sur chaque invocation au flux de journaux et transmet les journaux et autres sorties provenant du code de votre fonction. Pour de plus amples informations, veuillez consulter [Envoi automatique des journaux de la fonction Lambda à CloudWatch Logs](monitoring-cloudwatchlogs.md). Pour plus d'informations sur la configuration des formats de journal, consultez[Configuration des formats de journal JSON et en texte brut](monitoring-cloudwatchlogs-logformat.md). Cette page décrit comment produire des journaux à partir du code de votre fonction Lambda.

## Création d’une fonction qui écrit des journaux
<a name="rust-logging-function"></a>

Pour produire des journaux à partir du code de votre fonction, vous pouvez utiliser n’importe quelle fonction de journalisation qui écrit dans `stdout` ou `stderr`, comme la macro `println!`. L’exemple suivant utilise `println!` pour imprimer un message lorsque le gestionnaire de fonction démarre et avant qu’il ne se termine.

```
use lambda_runtime::{service_fn, LambdaEvent, Error};
use serde_json::{json, Value};
async fn handler(event: LambdaEvent<Value>) -> Result<Value, Error> {
    println!("Rust function invoked");
    let payload = event.payload;
    let first_name = payload["firstName"].as_str().unwrap_or("world");
    println!("Rust function responds to {}", &first_name);
    Ok(json!({ "message": format!("Hello, {first_name}!") }))
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    lambda_runtime::run(service_fn(handler)).await
}
```

## Implémentation de la journalisation avancée avec la caisse Tracing
<a name="rust-logging-tracing"></a>

[Tracing](https://crates.io/crates/tracing) est un cadre permettant d’instrumenter les programmes Rust afin de collecter des informations de diagnostic structurées et basées sur des événements. Ce cadre fournit des utilitaires pour personnaliser les niveaux et les formats de sortie des journaux, comme la création de messages de journal JSON structurés. Pour utiliser ce cadre, vous devez initialiser un `subscriber` avant de mettre en œuvre le gestionnaire de fonction. Ensuite, vous pouvez utiliser des macros de traçage comme `debug`, `info` et `error` pour spécifier le niveau de journal que vous voulez pour chaque scénario.

**Example – Utilisation de la caisse Tracing**  
Notez ce qui suit :  
+ `tracing_subscriber::fmt().json()` : lorsque cette option est incluse, les journaux sont formatés en JSON. Pour utiliser cette option, vous devez inclure la fonction `json` dans la dépendance `tracing-subscriber` (par exemple, `tracing-subscriber = { version = "0.3.11", features = ["json"] }`).
+ `#[tracing::instrument(skip(event), fields(req_id = %event.context.request_id))]` : cette annotation génère une étendue à chaque fois que le gestionnaire est invoqué. L’étendue ajoute l’identifiant de la demande à chaque ligne de journal.
+ `{ %first_name }` : cette construction ajoute le champ `first_name` à la ligne de journal où il est utilisé. La valeur de ce champ correspond à la variable du même nom.

```
use lambda_runtime::{service_fn, Error, LambdaEvent};
use serde_json::{json, Value};
#[tracing::instrument(skip(event), fields(req_id = %event.context.request_id))]
async fn handler(event: LambdaEvent<Value>) -> Result<Value, Error> {
    tracing::info!("Rust function invoked");
    let payload = event.payload;
    let first_name = payload["firstName"].as_str().unwrap_or("world");
    tracing::info!({ %first_name }, "Rust function responds to event");
    Ok(json!({ "message": format!("Hello, {first_name}!") }))
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    tracing_subscriber::fmt().json()
        .with_max_level(tracing::Level::INFO)
        // this needs to be set to remove duplicated information in the log.
        .with_current_span(false)
        // this needs to be set to false, otherwise ANSI color codes will
        // show up in a confusing manner in CloudWatch logs.
        .with_ansi(false)
        // disabling time is handy because CloudWatch will add the ingestion time.
        .without_time()
        // remove the name of the function from every log entry
        .with_target(false)
        .init();
    lambda_runtime::run(service_fn(handler)).await
}
```

Lorsque cette fonction Rust est invoquée, elle imprime deux lignes de journal similaires à ce qui suit :

```
{"level":"INFO","fields":{"message":"Rust function invoked"},"spans":[{"req_id":"45daaaa7-1a72-470c-9a62-e79860044bb5","name":"handler"}]}
{"level":"INFO","fields":{"message":"Rust function responds to event","first_name":"David"},"spans":[{"req_id":"45daaaa7-1a72-470c-9a62-e79860044bb5","name":"handler"}]}
```