

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Compilazione di funzioni Lambda con Rust
<a name="lambda-rust"></a>

Poiché Rust viene compilato in codice nativo, non è necessario un runtime dedicato per eseguire il codice Rust su Lambda. Utilizza invece il [client di runtime Rust](https://github.com/aws/aws-lambda-rust-runtime) per creare il tuo progetto localmente, quindi distribuiscilo su Lambda utilizzando [un](runtimes-provided.md) runtime solo per il sistema operativo. Quando utilizzi un runtime solo per il sistema operativo, Lambda mantiene automaticamente il sistema operativo aggiornato con le patch più recenti.

**Strumenti e librerie per Rust**
+ [AWS SDK per Rust](https://docs.aws.amazon.com/sdk-for-rust/latest/dg/getting-started.html): L' AWS SDK per Rust consente APIs a Rust di interagire con i servizi di infrastruttura Amazon Web Services.
+  [Client di runtime Rust per Lambda](https://github.com/aws/aws-lambda-rust-runtime): Il client di runtime Rust semplifica l'esecuzione di funzioni Lambda scritte in Rust.
+ [Cargo Lambda](https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html): si tratta di un'estensione open source di terze parti dello strumento da riga di comando Cargo che semplifica la creazione e l'implementazione di funzioni Rust Lambda.
+ [HTTP Lambda](https://github.com/aws/aws-lambda-rust-runtime/tree/main/lambda-http): questa libreria fornisce un wrapper per lavorare con gli eventi HTTP.
+  [Estensione Lambda](https://github.com/aws/aws-lambda-rust-runtime/tree/main/lambda-extension): questa libreria fornisce supporto per scrivere estensioni Lambda con Rust. 
+ [AWS Lambda Eventi](https://crates.io/crates/aws_lambda_events): questa libreria fornisce definizioni dei tipi per le integrazioni di sorgenti di eventi comuni.

**Esempi di applicazioni Lambda per Rust**
+ [Funzione Lambda di base](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/basic-lambda): una funzione Rust che mostra come elaborare gli eventi di base.
+ [Funzione Lambda con gestione degli errori](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/basic-error-handling): una funzione Rust che mostra come gestire gli errori Rust personalizzati in Lambda.
+ [Funzione Lambda con risorse condivise](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/basic-shared-resource): un progetto Rust che inizializza le risorse condivise prima della creazione della funzione Lambda.
+ [Eventi HTTP Lambda](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/http-basic-lambda): una funzione Rust che gestisce gli eventi HTTP.
+ [Eventi HTTP Lambda con intestazioni CORS](https://github.com/aws/aws-lambda-rust-runtime/blob/main//examples/http-cors): una funzione Rust che utilizza Tower per inserire le intestazioni CORS.
+ [REST API Lambda](https://github.com/aws/aws-lambda-rust-runtime/tree/main/examples/http-axum-diesel): una REST API che utilizza Axum e Diesel per connettersi a un database PostgreSQL.
+ [Demo di Rust senza server](https://github.com/aws-samples/serverless-rust-demo/): un progetto Rust che mostra l'uso delle librerie Rust di Lambda, la registrazione, le variabili di ambiente e l'SDK. AWS 
+ [Estensione Lambda di base](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/extension-basic): un'estensione Rust che mostra come elaborare gli eventi di estensione di base.
+ [Estensione Amazon Data Firehose per i log Lambda](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/extension-logs-kinesis-firehose): un'estensione Rust che mostra come inviare log Lambda a Firehose.

**Topics**
+ [

# Definisci i gestori di funzioni Lambda in Rust
](rust-handler.md)
+ [

# Utilizzo dell'oggetto contestuale Lambda per recuperare le informazioni sulla funzione Rust
](rust-context.md)
+ [

# Elaborazione di eventi HTTP con Rust
](rust-http-events.md)
+ [

# Implementazione di funzioni Lambda per Go con gli archivi di file .zip
](rust-package.md)
+ [

# Utilizzo dei livelli per le funzioni Lambda in Go
](rust-layers.md)
+ [

# Registrare e monitorare le funzioni Lambda con Rust
](rust-logging.md)

# Definisci i gestori di funzioni Lambda in Rust
<a name="rust-handler"></a>

Il *gestore* di funzioni Lambda è il metodo nel codice della funzione che elabora gli eventi. Quando viene richiamata la funzione, Lambda esegue il metodo del gestore. La funzione viene eseguita fino a quando il gestore non restituisce una risposta, termina o scade.

Questa pagina descrive come lavorare con i gestori di funzioni Lambda in Rust, tra cui l'inizializzazione del progetto, le convenzioni di denominazione e le migliori pratiche. Questa pagina include anche un esempio di funzione Rust Lambda che raccoglie informazioni su un ordine, produce una ricevuta in un file di testo e inserisce questo file in un bucket Amazon Simple Storage Service (S3). Per ulteriori informazioni su come distribuire una funzione dopo averla scritta, consulta. [Implementazione di funzioni Lambda per Go con gli archivi di file .zip](rust-package.md)

**Topics**
+ [

## Configurazione del progetto Rust Handler
](#rust-handler-setup)
+ [

## Esempio di codice della funzione Rust Lambda
](#rust-example-code)
+ [

## Definizioni di classe valide per i gestori Rust
](#rust-handler-signatures)
+ [

## Convenzioni di denominazione dei gestori
](#rust-example-naming)
+ [

## Definizione e accesso all'oggetto evento di input
](#rust-handler-input)
+ [

## Accesso e utilizzo dell'oggetto contestuale Lambda
](#rust-example-context)
+ [

## Usando il nel tuo gestore AWS SDK per Rust
](#rust-example-sdk-usage)
+ [

## Accesso alle variabili d'ambiente
](#rust-example-envvars)
+ [

## Utilizzo dello stato condiviso
](#rust-shared-state)
+ [

## Best practice di codice per funzioni Lambda in Rust
](#rust-best-practices)

## Configurazione del progetto Rust Handler
<a name="rust-handler-setup"></a>

Quando si lavora con le funzioni Lambda in Rust, il processo prevede la scrittura del codice, la compilazione e la distribuzione degli artefatti compilati in Lambda. Il modo più semplice per configurare un progetto di gestione Lambda in Rust consiste nell'utilizzare il [AWS Lambda Runtime](https://github.com/aws/aws-lambda-rust-runtime) for Rust. Nonostante il nome, AWS Lambda Runtime for Rust non è un runtime gestito nello stesso senso in cui lo è in Lambda for Python, Java o Node.js. Invece, il AWS Lambda Runtime for Rust è un crate (`lambda_runtime`) che supporta la scrittura di funzioni Lambda in Rust e l'interfacciamento AWS Lambda con l'ambiente di esecuzione.

Usa il seguente comando per installare [Cargo Lambda](https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html), un'estensione open source di terze parti per lo strumento da riga di comando Cargo che semplifica la creazione e l'implementazione di funzioni Rust Lambda:

```
cargo install cargo-lambda
```

Dopo aver installato correttamente`cargo-lambda`, usa il seguente comando per inizializzare un nuovo progetto di gestore di funzioni Rust Lambda:

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

Quando esegui questo comando, l'interfaccia a riga di comando (CLI) ti pone un paio di domande sulla tua funzione Lambda:
+ **Funzione HTTP**: se intendi richiamare la tua funzione tramite [API Gateway](services-apigateway.md) o un [URL di funzione](urls-configuration.md), rispondi **Sì**. Altrimenti, rispondi **No.** **Nel codice di esempio in questa pagina, invochiamo la nostra funzione con un evento JSON personalizzato, quindi rispondiamo No.**
+ **Tipo di evento**: se intendi utilizzare una forma di evento predefinita per richiamare la funzione, seleziona il tipo di evento previsto corretto. Altrimenti, lasciate vuota questa opzione. Nel codice di esempio in questa pagina, invochiamo la nostra funzione con un evento JSON personalizzato, quindi lasciamo vuota questa opzione.

Dopo che il comando è stato eseguito correttamente, accedi alla directory principale del tuo progetto:

```
cd example-rust
```

Questo comando genera un `generic_handler.rs` file e un `main.rs` file nella `src` directory. `generic_handler.rs`Può essere usato per personalizzare un gestore di eventi generico. Il `main.rs` file contiene la logica principale dell'applicazione. Il `Cargo.toml` file contiene metadati sul pacchetto ed elenca le sue dipendenze esterne.

## Esempio di codice della funzione Rust Lambda
<a name="rust-example-code"></a>

Il seguente esempio di codice della funzione Rust Lambda raccoglie informazioni su un ordine, produce una ricevuta in un file di testo e inserisce questo file in un bucket Amazon S3.

**Example Funzione 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
}
```

Questo file `main.rs` contiene le sezioni seguenti:
+ `use`istruzioni: usale per importare casse e metodi Rust richiesti dalla tua funzione Lambda.
+ `#[derive(Deserialize, Serialize)]`: definisci la forma dell'evento di input previsto in questa struttura Rust.
+ `async fn function_handler(event: LambdaEvent<Value>) -> Result<String, Error>`: questo è il **metodo dell'handler principale**, che contiene la logica principale dell'applicazione.
+ `async fn upload_receipt_to_s3 (...)`: Questo è un metodo di supporto a cui fa riferimento il metodo principale`function_handler`.
+ `#[tokio::main]`: Questa è una macro che segna il punto di ingresso di un programma Rust. Imposta anche un [runtime Tokio](https://docs.rs/tokio/latest/tokio/runtime/index.html), che consente al `main()` metodo di utilizzare`async`/`await`ed eseguire in modo asincrono.
+ `async fn main() -> Result<(), Error>`: La `main()` funzione è il punto di ingresso del codice. Al suo interno, specifichiamo `function_handler` come metodo di gestione principale.

### File Cargo.toml di esempio
<a name="rust-cargo-toml"></a>

Il seguente `Cargo.toml` file accompagna questa funzione.

```
[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"] }
```

Affinché questa funzione funzioni correttamente, il suo [ruolo di esecuzione](lambda-intro-execution-role.md) deve consentire l'`s3:PutObject`azione. Inoltre, assicuratevi di definire la variabile di `RECEIPT_BUCKET` ambiente. Dopo una chiamata riuscita, il bucket Amazon S3 dovrebbe contenere un file di ricevuta.

## Definizioni di classe valide per i gestori Rust
<a name="rust-handler-signatures"></a>

Nella maggior parte dei casi, le firme dei gestori Lambda definite in Rust avranno il seguente formato:

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

Per questo gestore:
+ Il nome di questo gestore è. `function_handler`
+ L'input singolare al gestore è evento ed è di tipo. `LambdaEvent<T>`
  + `LambdaEvent`è un wrapper che proviene dalla cassa. `lambda_runtime` L'utilizzo di questo wrapper consente di accedere all'oggetto di contesto, che include metadati specifici di Lambda come l'ID della richiesta della chiamata.
  + `T`è il tipo di evento deserializzato. Ad esempio, questo può essere`serde_json::Value`, che consente al gestore di accettare qualsiasi input JSON generico. In alternativa, questo può essere un tipo come `ApiGatewayProxyRequest` se la funzione si aspettasse un tipo di input specifico e predefinito.
+ Il tipo restituito dal gestore è. `Result<U, Error>`
  + `U`è il tipo di output deserializzato. `U`deve implementare il `serde::Serialize` tratto in modo che Lambda possa convertire il valore restituito in JSON. Ad esempio, `U` può essere un tipo `String` semplice o una struttura personalizzata purché implementata. `serde_json::Value` `Serialize` Quando il codice raggiunge un'istruzione Ok (U), ciò indica che l'esecuzione è riuscita e la funzione restituisce un valore di tipo`U`.
  + Quando il codice rileva un errore (ad esempio`Err(Error)`), la funzione registra l'errore in Amazon CloudWatch e restituisce una risposta di errore di tipo. `Error`

Nel nostro esempio, la firma del gestore ha il seguente aspetto:

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

Altre firme valide del gestore possono presentare quanto segue:
+ Omissione del `LambdaEvent` wrapper: se si omette`LambdaEvent`, si perde l'accesso all'oggetto di contesto Lambda all'interno della funzione. Di seguito è riportato un esempio di questo tipo di firma:

  ```
  async fn handler(event: serde_json::Value) -> Result<String, Error>
  ```
+ Utilizzo del tipo di unità come input — Per Rust, puoi usare il tipo di unità per rappresentare un input vuoto. Questo è comunemente usato per funzioni con invocazioni periodiche e programmate. Di seguito è riportato un esempio di questo tipo di firma:

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

## Convenzioni di denominazione dei gestori
<a name="rust-example-naming"></a>

I gestori Lambda in Rust non hanno rigide restrizioni di denominazione. Sebbene sia possibile utilizzare qualsiasi nome per il gestore, i nomi delle funzioni in Rust sono generalmente in. `snake_case`

Per applicazioni più piccole, come in questo esempio, puoi usare un singolo `main.rs` file per contenere tutto il codice. Per progetti più grandi, `main.rs` deve contenere il punto di ingresso alla funzione, ma è possibile disporre di file aggiuntivi per separare il codice in moduli logici. Ad esempio, potresti avere la seguente struttura di file:

```
/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
```

## Definizione e accesso all'oggetto evento di input
<a name="rust-handler-input"></a>

JSON è il formato di input più comune e standard per le funzioni Lambda. In questo esempio, la funzione prevede un input simile a quanto segue:

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

In Rust, puoi definire la forma dell'evento di input previsto in una struttura. In questo esempio, definiamo la seguente struttura per rappresentare un`Order`:

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

Questa struttura corrisponde alla forma di input prevista. In questo esempio, la `#[derive(Deserialize, Serialize)]` macro genera automaticamente codice per la serializzazione e la deserializzazione. Ciò significa che possiamo deserializzare il tipo JSON di input generico nella nostra struttura utilizzando il metodo. `serde_json::from_value()` Ciò è illustrato nelle prime righe dell'handler:

```
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)?;
    ...
}
```

È quindi possibile accedere ai campi dell'oggetto. Ad esempio, `order.order_id` recupera il valore di `order_id` dall'input originale.

### Tipi di eventi di input predefiniti
<a name="rust-input-event-types"></a>

Nella cassa sono disponibili molti tipi di eventi di input predefiniti. `aws_lambda_events` Ad esempio, se intendi richiamare la tua funzione con API Gateway, inclusa la seguente importazione:

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

Quindi, assicurati che il tuo gestore principale utilizzi la seguente firma:

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

Fai riferimento alla [cassa aws\$1lambda\$1events per ulteriori informazioni su altri tipi di eventi di](https://crates.io/crates/aws_lambda_events) input predefiniti.

## Accesso e utilizzo dell'oggetto contestuale Lambda
<a name="rust-example-context"></a>

L'[oggetto contesto](rust-context.md): contiene informazioni sulla chiamata, sulla funzione e sull'ambiente di esecuzione. In Rust, il wrapper include l'oggetto context. `LambdaEvent` Ad esempio, è possibile utilizzare l'oggetto context per recuperare l'ID di richiesta della chiamata corrente con il seguente codice:

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

Per ulteriori informazioni sulla copia di oggetti, consulta la sezione [Utilizzo dell'oggetto contestuale Lambda per recuperare le informazioni sulla funzione Rust](rust-context.md).

## Usando il nel tuo gestore AWS SDK per Rust
<a name="rust-example-sdk-usage"></a>

Spesso, utilizzerai le funzioni Lambda per interagire o aggiornare altre AWS risorse. Il modo più semplice per interfacciarsi con queste risorse consiste nell'utilizzare il [AWS SDK per Rust](https://docs.aws.amazon.com/sdk-for-rust/latest/dg/welcome.html).

Per aggiungere dipendenze SDK alla tua funzione, aggiungile nel tuo `Cargo.toml` file. Ti consigliamo di aggiungere solo le librerie necessarie per la tua funzione. Nel codice di esempio precedente, abbiamo usato il`aws_sdk_s3::Client`. Nel `Cargo.toml` file, puoi aggiungere questa dipendenza aggiungendo la seguente riga nella `[dependencies]` sezione:

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

**Nota**  
Questa potrebbe non essere la versione più recente. Scegli la versione appropriata per la tua applicazione.

Quindi, importa le dipendenze direttamente nel tuo codice:

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

Il codice di esempio inizializza quindi un client Amazon S3 come segue:

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

Dopo aver inizializzato il client SDK, puoi utilizzarlo per interagire con altri servizi. AWS Il codice di esempio richiama l'`PutObject`API Amazon S3 nella funzione `upload_receipt_to_s3` helper.

## Accesso alle variabili d'ambiente
<a name="rust-example-envvars"></a>

Nel codice dell'handler, puoi fare riferimento a qualsiasi [variabile di ambiente](configuration-envvars.md) utilizzando il metodo `env::var`. In questo esempio, facciamo riferimento alla variabile di `RECEIPT_BUCKET` ambiente definita utilizzando la seguente riga di codice:

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

## Utilizzo dello stato condiviso
<a name="rust-shared-state"></a>

È possibile dichiarare delle variabili condivise indipendenti dal codice del gestore della funzione Lambda. Queste variabili possono aiutarti a caricare le informazioni sullo stato durante i [Fase di init](lambda-runtime-environment.md#runtimes-lifecycle-ib), prima che la funzione riceva eventi. Ad esempio, puoi modificare il codice in questa pagina per utilizzare lo stato condiviso durante l'inizializzazione del client Amazon S3 aggiornando la funzione e la firma `main` del gestore:

```
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
```

## Best practice di codice per funzioni Lambda in Rust
<a name="rust-best-practices"></a>

Segui le linee guida riportate nell'elenco seguente per utilizzare le best practice di codifica durante la creazione delle funzioni Lambda:
+ **Separare il gestore Lambda dalla logica principale.** In questo modo è possibile creare una funzione di cui è più semplice eseguire l'unit test.
+ **Ridurre la complessità delle dipendenze.** Preferire framework più semplici che si caricano velocemente all'avvio del [contesto di esecuzione](lambda-runtime-environment.md).
+ **Ridurre al minimo le dimensioni del pacchetto di implementazione al fine di soddisfare le esigenze di runtime. ** In questo modo viene ridotta la quantità di tempo necessaria per il download del pacchetto e per la relativa decompressione prima dell'invocazione.

**Sfruttare il riutilizzo del contesto di esecuzione per migliorare le prestazioni della funzione.** Inizializzare i client SDK e le connessioni al database all'esterno del gestore di funzioni e memorizzare localmente nella cache gli asset statici nella directory `/tmp`. Le chiamate successive elaborate dalla stessa istanza della funzione possono riutilizzare queste risorse. Ciò consente di risparmiare sui costi riducendo i tempi di esecuzione delle funzioni.

Per evitare potenziali perdite di dati tra le chiamate, non utilizzare il contesto di esecuzione per archiviare dati utente, eventi o altre informazioni con implicazioni di sicurezza. Se la funzione si basa su uno stato mutabile che non può essere archiviato in memoria all'interno del gestore, considerare la possibilità di creare una funzione separata o versioni separate di una funzione per ogni utente.

**Utilizzare una direttiva keep-alive per mantenere le connessioni persistenti.** Lambda elimina le connessioni inattive nel tempo. Se si tenta di riutilizzare una connessione inattiva quando si richiama una funzione, si verificherà un errore di connessione. Per mantenere la connessione persistente, utilizzare la direttiva keep-alive associata al runtime. Per un esempio, vedere [Riutilizzo delle connessioni con Keep-Alive in Node.js](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html).

**Utilizzare [le variabili di ambiente](configuration-envvars.md) per passare i parametri operativi alla funzione.** Se ad esempio si scrive in un bucket Amazon S3 anziché impostare come hard-coded il nome del bucket in cui si esegue la scrittura, configurare tale nome come una variabile di ambiente.

**Evita di usare invocazioni ricorsive** nella tua funzione Lambda, in cui la funzione si richiama da sola o avvia un processo che potrebbe richiamare nuovamente la funzione. Ciò potrebbe provocare un volume non desiderato di invocazioni della funzione e un aumento dei costi. Se noti un volume indesiderato di invocazioni, imposta immediatamente la simultaneità riservata della funzione su `0` per interrompere tutte le invocazioni della funzione mentre si aggiorna il codice.

**Non utilizzare documenti non documentati e non pubblici APIs** nel codice della funzione Lambda. Per i runtime AWS Lambda gestiti, Lambda applica periodicamente aggiornamenti di sicurezza e funzionalità all'interno di Lambda. APIs Questi aggiornamenti delle API interne possono essere incompatibili con le versioni precedenti e portare a conseguenze indesiderate, come errori di chiamata se la funzione dipende da questi elementi non pubblici. APIs [Consulta il riferimento alle API per un elenco di quelle disponibili al pubblico.](https://docs.aws.amazon.com/lambda/latest/api/welcome.html) APIs

**Scrivi un codice idempotente.** La scrittura di un codice idempotente per le tue funzioni garantisce che gli eventi duplicati vengano gestiti allo stesso modo. Il tuo codice dovrebbe convalidare correttamente gli eventi e gestire con garbo gli eventi duplicati. Per ulteriori informazioni, consulta [Come posso rendere idempotente la mia funzione Lambda?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/).

# Utilizzo dell'oggetto contestuale Lambda per recuperare le informazioni sulla funzione Rust
<a name="rust-context"></a>

Quando Lambda esegue la funzione, aggiunge un oggetto di contesto a LambdaEvent quello ricevuto dal [gestore](rust-handler.md). Questo oggetto fornisce proprietà con informazioni sulla chiamata, sulla funzione e sull'ambiente di esecuzione.

**Proprietà del contesto**
+  `request_id`: l'ID della AWS richiesta generato dal servizio Lambda. 
+  `deadline`: la scadenza di esecuzione per la chiamata corrente in millisecondi.
+  `invoked_function_arn`: il nome della risorsa Amazon (ARN) della funzione Lambda da richiamare.
+  `xray_trace_id`: L'ID di AWS X-Ray traccia per la chiamata corrente. 
+  `client_content`: l'oggetto contestuale del client inviato dall'SDK AWS mobile. Questo campo è vuoto a meno che la funzione non venga richiamata utilizzando un SDK AWS mobile. 
+  `identity`: l'identità Amazon Cognito che ha richiamato la funzione. Questo campo è vuoto a meno che la richiesta di chiamata a Lambda non sia APIs stata effettuata utilizzando AWS credenziali emesse dai pool di identità di Amazon Cognito.
+  `env_config`: la configurazione della funzione Lambda in base alle variabili di ambiente locali. Questa proprietà include informazioni come il nome della funzione, l'allocazione della memoria, la versione e i flussi di log.

## Accesso alle informazioni relative al contesto di invocazione
<a name="rust-context-invoke"></a>

Le funzioni Lambda hanno accesso ai metadata relativi al loro ambiente e alla richiesta di invocazione. L'oggetto `LambaEvent` ricevuto dal gestore delle funzioni include i metadati `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
}
```

# Elaborazione di eventi HTTP con Rust
<a name="rust-http-events"></a>

Amazon API Gateway APIs, Application Load Balancers e la [funzione Lambda URLs](urls-configuration.md) possono inviare eventi HTTP a Lambda. Puoi utilizzare la cassa [aws\$1lambda\$1events](https://crates.io/crates/aws_lambda_events) di crates.io per elaborare gli eventi da queste origini.

**Example - Gestione della richiesta proxy di Gateway API**  
Tenere presente quanto segue:  
+ `use aws_lambda_events::apigw::{ApiGatewayProxyRequest, ApiGatewayProxyResponse}`: la cassa [aws\$1lambda\$1events](https://crates.io/crates/aws-lambda-events) include molti eventi Lambda. Per ridurre i tempi di compilazione, utilizza i flag delle funzionalità per attivare gli eventi di cui hai bisogno. Esempio: `aws_lambda_events = { version = "0.8.3", default-features = false, features = ["apigw"] }`.
+ `use http::HeaderMap`: questa importazione richiede l'aggiunta della cassa [http](https://crates.io/crates/http) alle dipendenze.

```
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
}
```

Il [client di runtime Rust per Lambda](https://github.com/aws/aws-lambda-rust-runtime) fornisce anche un'astrazione su questi tipi di eventi che consente di lavorare con tipi HTTP nativi, indipendentemente dal servizio che invia gli eventi. Il codice seguente è equivalente all'esempio precedente e funziona immediatamente con la funzione Lambda URLs, Application Load Balancers e API Gateway.

**Nota**  
La cassa [lambda\$1http](https://crates.io/crates/lambda_http) utilizza la cassa [lambda\$1runtime](https://crates.io/crates/lambda_runtime) sottostante. Non è necessario eseguire l'importazione di `lambda_runtime` separatamente.

**Example - Gestione delle richieste 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
}
```

Per un altro esempio di utilizzo`lambda_http`, consultate l'esempio di [codice http-axum](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/http-axum/src/main.rs) nel repository Labs. AWS GitHub 

**Eventi HTTP Lambda di esempio per Rust**
+ [Eventi HTTP Lambda](https://github.com/aws/aws-lambda-rust-runtime/tree/main/examples/http-basic-lambda): una funzione Rust che gestisce gli eventi HTTP.
+ [Eventi HTTP Lambda con intestazioni CORS](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/http-cors): una funzione Rust che utilizza Tower per inserire le intestazioni CORS.
+ [Eventi HTTP Lambda con risorse condivise](https://github.com/aws/aws-lambda-rust-runtime/tree/main/examples/basic-shared-resource): una funzione Rust che utilizza risorse condivise inizializzate prima della creazione del gestore della funzione.

# Implementazione di funzioni Lambda per Go con gli archivi di file .zip
<a name="rust-package"></a>

Questa pagina descrive come compilare la funzione Rust e quindi distribuire il binario compilato su Cargo [Lambda AWS Lambda](https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html). Mostra anche come distribuire il binario compilato con AWS Command Line Interface e la AWS Serverless Application Model CLI.

**Topics**
+ [

## Prerequisiti
](#rust-package-prerequisites)
+ [

## Compilazione di funzioni Rust su macOS, Windows o Linux
](#rust-package-build)
+ [

## Implementazione del file binario di funzioni Rust con Cargo Lambda
](#rust-deploy-cargo)
+ [

## Richiamo della funzione Rust con Cargo Lambda
](#rust-invoke-function)

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

## Compilazione di funzioni Rust su macOS, Windows o Linux
<a name="rust-package-build"></a>

I passaggi seguenti mostrano come creare il progetto per la prima funzione Lambda con Rust e compilarlo con Cargo Lambda, un'estensione open source di terze parti dello [strumento da riga di comando Cargo che semplifica la creazione e l'implementazione di funzioni Rust Lambda](https://www.cargo-lambda.info/).

1. Installa [Cargo Lambda](https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html), un'estensione open source di terze parti per lo strumento da riga di comando Cargo che semplifica la creazione e l'implementazione di funzioni Rust Lambda:

   ```
   cargo install cargo-lambda
   ```

   Per altre opzioni di installazione, consulta [Installazione](https://www.cargo-lambda.info/guide/installation.html) nella documentazione di Cargo Lambda.

1. Crea la struttura del pacchetto. Questo comando crea un codice di funzione di base in `src/main.rs`. A fini di test, puoi utilizzare questo codice o sostituirlo con il tuo codice personalizzato.

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

1. All'interno della directory principale del pacchetto, esegui il sottocomando [build](https://www.cargo-lambda.info/commands/build.html) per compilare il codice nella funzione.

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

   (Facoltativo) Se vuoi usare AWS Graviton2 su Lambda, aggiungi il `--arm64` flag per compilare il codice per ARM. CPUs

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

1. Prima di distribuire la funzione Rust, configura le credenziali sulla tua macchina. AWS 

   ```
   aws configure
   ```

## Implementazione del file binario di funzioni Rust con Cargo Lambda
<a name="rust-deploy-cargo"></a>

Utilizza il sottocomando [deploy](https://www.cargo-lambda.info/commands/deploy.html) per implementare il file binario compilato su Lambda. Questo comando crea un [ruolo di esecuzione](lambda-intro-execution-role.md) e quindi crea la funzione Lambda. Per specificare un ruolo di esecuzione esistente, utilizza il [flag --iam-role](https://www.cargo-lambda.info/commands/deploy.html#iam-roles).

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

### Distribuzione del file binario della funzione Rust con AWS CLI
<a name="rust-deploy-aws-cli"></a>

Puoi anche distribuire il tuo file binario con. AWS CLI

1. Per compilare il pacchetto di implementazione .zip, utilizza il sottocomando [build](https://www.cargo-lambda.info/commands/build.html).

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

1. Per implementare il pacchetto .zip su Lambda, eseguire il comando [create-function](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-function.html).
   + Per `--runtime`, specificare `provided.al2023`. Questo è un [runtime solo per il sistema operativo](runtimes-provided.md). I runtime solo per il sistema operativo vengono utilizzati per distribuire file binari compilati e runtime personalizzati su Lambda.
   + Per `--role`, specifica l'ARN del [ruolo di esecuzione](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
   ```

### Distribuzione del binario della funzione Rust con la CLI AWS SAM
<a name="rust-deploy-sam-cli"></a>

Puoi anche distribuire il tuo file binario con la AWS SAM CLI.

1. Crea un AWS SAM modello con la definizione delle risorse e delle proprietà. Per `Runtime`, specificare `provided.al2023`. Questo è un [runtime solo per il sistema operativo](runtimes-provided.md). I runtime solo per il sistema operativo vengono utilizzati per distribuire file binari compilati e runtime personalizzati su Lambda.

   Per ulteriori informazioni sulla distribuzione delle funzioni Lambda AWS SAM utilizzando, [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)consulta la Guida per *AWS Serverless Application Model gli* sviluppatori.  
**Example Definizione di risorse e proprietà SAM per un file binario 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. Utilizza il sottocomando [build](https://www.cargo-lambda.info/commands/build.html) per compilare la funzione.

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

1. Utilizza il comando [sam deploy](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-deploy.html) per implementare la funzione su Lambda.

   ```
   sam deploy --guided
   ```

*Per ulteriori informazioni sulla creazione di funzioni Rust con la AWS SAM CLI, consulta [Creazione di funzioni Rust Lambda con Cargo Lambda nella Developer Guide](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/building-rust.html).AWS Serverless Application Model *

## Richiamo della funzione Rust con Cargo Lambda
<a name="rust-invoke-function"></a>

Utilizza il sottocomando [invoke](https://www.cargo-lambda.info/commands/invoke.html) per testare la tua funzione con un payload.

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

### Invocare la funzione Rust con AWS CLI
<a name="rust-invoke-cli"></a>

Puoi anche usare il AWS CLI per richiamare la funzione.

```
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**opzione è obbligatoria se si utilizza la AWS CLI versione 2. Per rendere questa impostazione come predefinita, esegui `aws configure set cli-binary-format raw-in-base64-out`. Per ulteriori informazioni, consulta la pagina [AWS CLI supported global command line options](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) nella *Guida per l'utente di AWS Command Line Interface versione 2*.

# Utilizzo dei livelli per le funzioni Lambda in Go
<a name="rust-layers"></a>

Consigliamo di non utilizzare i livelli per gestire le dipendenze per le funzioni Lambda scritte in Go. Questo perché le funzioni Lambda in Go vengono compilate in un unico eseguibile, che viene fornito a Lambda quando si distribuisce la funzione. Questo eseguibile contiene il codice di funzione compilato, insieme a tutte le sue dipendenze. L'uso dei livelli non solo complica questo processo, ma comporta anche un aumento dei tempi di avvio a freddo, poiché le funzioni devono caricare manualmente assiemi aggiuntivi in memoria durante la fase di inizializzazione.

Per utilizzare dipendenze esterne con i gestori Go, includile direttamente nel pacchetto di implementazione. In questo modo, semplifichi il processo di implementazione e sfrutti anche le ottimizzazioni integrate del compilatore Go. Per un esempio di come importare e utilizzare una dipendenza come l'SDK AWS per Go nella tua funzione, consulta [Definisci i gestori di funzioni Lambda in Rust](rust-handler.md).

# Registrare e monitorare le funzioni Lambda con Rust
<a name="rust-logging"></a>

AWS Lambda monitora automaticamente le funzioni Lambda per tuo conto e invia i log ad Amazon. CloudWatch La funzione Lambda include un gruppo di log CloudWatch Logs e un flusso di log per ogni istanza della funzione. L'ambiente del runtime Lambda invia i dettagli su ogni richiamo al flusso di log e inoltra i log e l'output del codice della funzione. Per ulteriori informazioni, consulta [Lambda invia automaticamente i log delle funzioni a CloudWatch Logs.](monitoring-cloudwatchlogs.md). Per informazioni sulla configurazione dei formati di registro, consulta. [Configurazione dei formati di log JSON e testo normale](monitoring-cloudwatchlogs-logformat.md) In questa pagina viene descritto come generare l'output del log dal codice della funzione Lambda.

## Creazione di una funzione che scrive i log
<a name="rust-logging-function"></a>

Per generare i log dal codice della funzione, è possibile utilizzare qualsiasi funzione di registrazione che scriva in `stdout` o `stderr`, come la macro `println!`. L'esempio seguente utilizza `println!` per stampare un messaggio all'avvio del gestore della funzione e prima che finisca.

```
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
}
```

## Registrazione avanzata con la cassa Tracing
<a name="rust-logging-tracing"></a>

[Tracing](https://crates.io/crates/tracing) è un framework che consente di strumentare i programmi Rust per raccogliere informazioni diagnostiche strutturate e basate sugli eventi. Questo framework fornisce utilità per personalizzare i livelli e i formati di output di registrazione, come la creazione di messaggi di log JSON strutturati. Per utilizzare questo framework, è necessario inizializzare un `subscriber` prima di implementare il gestore della funzione. Dopodiché, è possibile utilizzare macro di tracciamento come `debug`, `info` e `error` per specificare il livello di registrazione desiderato per ogni scenario.

**Example - Utilizzo della cassa Tracing**  
Tenere presente quanto segue:  
+ `tracing_subscriber::fmt().json()`: quando questa opzione è inclusa, i log vengono formattati in JSON. Per utilizzare questa opzione, è necessario includere la funzionalità `json` nella dipendenza `tracing-subscriber` (ad esempio, `tracing-subscriber = { version = "0.3.11", features = ["json"] }`).
+ `#[tracing::instrument(skip(event), fields(req_id = %event.context.request_id))]`: questa annotazione genera un intervallo ogni volta che viene richiamato il gestore. L'intervallo aggiunge l'ID della richiesta su ciascuna riga di log.
+ `{ %first_name }`: questo costrutto aggiunge il campo `first_name` alla riga di log in cui viene utilizzato. Il valore di questo campo corrisponde alla variabile con lo stesso nome.

```
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
}
```

Quando viene richiamata questa funzione Rust, stampa due righe di log simili alle seguenti:

```
{"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"}]}
```