Definisci il gestore di funzioni Lambda in Rust - AWS Lambda

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à.

Definisci il gestore di funzioni Lambda in Rust

Nota

Il client di runtime Rust è un pacchetto sperimentale. È soggetto a modifiche ed è destinato esclusivamente a scopi di valutazione.

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.

Nozioni di base sul gestore Rust

Scrivi il codice della tua funzione Lambda come eseguibile Rust. Implementa il codice della funzione del gestore e una funzione principale e includi quanto segue:

Esempio — Gestore Rust che elabora gli eventi JSON

L'esempio seguente utilizza il crate serde_json per elaborare gli eventi di base: JSON

use lambda_runtime::{service_fn, LambdaEvent, Error}; use serde_json::{json, Value}; async fn handler(event: LambdaEvent<Value>) -> Result<Value, Error> { let payload = event.payload; let first_name = payload["firstName"].as_str().unwrap_or("world"); Ok(json!({ "message": format!("Hello, {first_name}!") })) } #[tokio::main] async fn main() -> Result<(), Error> { lambda_runtime::run(service_fn(handler)).await }

Tieni presente quanto segue:

  • use: importa le librerie richieste dalla funzione Lambda.

  • async fn main: il punto di ingresso che esegue il codice della funzione Lambda. Il client di runtime Rust utilizza Tokio come runtime asincrono, quindi è necessario annotare la funzione principale con #[tokio::main].

  • async fn handler(event: LambdaEvent<Value>) -> Result<Value,Error>: questa è la firma del gestore Lambda. Include del codice che viene eseguito quando la funzione viene richiamata.

    • LambdaEvent<Value>: si tratta di un tipo generico che descrive l'evento ricevuto dal runtime Lambda e dal contesto della funzione Lambda.

    • Result<Value, Error>: la funzione restituisce un tipo Result. Se la funzione ha successo, il risultato è un valore. JSON Se la funzione ha esito negativo, il risultato è un errore.

Utilizzo dello stato condiviso

È 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, prima che la funzione riceva eventi.

Esempio - Condivisione del client Amazon S3 tra istanze di funzione

Tieni presente quanto segue:

  • use aws_sdk_s3::Client: questo esempio richiede l'aggiunta di aws-sdk-s3 = "0.26.0" all'elenco delle dipendenze nel file Cargo.toml.

  • aws_config::from_env: questo esempio richiede l'aggiunta di aws-config = "0.55.1" all'elenco delle dipendenze nel file Cargo.toml.

use aws_sdk_s3::Client; use lambda_runtime::{service_fn, Error, LambdaEvent}; use serde::{Deserialize, Serialize}; #[derive(Deserialize)] struct Request { bucket: String, } #[derive(Serialize)] struct Response { keys: Vec<String>, } async fn handler(client: &Client, event: LambdaEvent<Request>) -> Result<Response, Error> { let bucket = event.payload.bucket; let objects = client.list_objects_v2().bucket(bucket).send().await?; let keys = objects .contents() .map(|s| s.iter().flat_map(|o| o.key().map(String::from)).collect()) .unwrap_or_default(); Ok(Response { keys }) } #[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 }

Procedure consigliate di codice per le funzioni Rust Lambda

Segui le linee guida riportate nell'elenco seguente per utilizzare le migliori pratiche 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.

  • 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. Inizializza SDK i client e le connessioni al database all'esterno del gestore delle funzioni e memorizza nella cache le risorse statiche localmente 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.

  • Utilizzare le variabili di ambiente 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 vedi un volume involontario di chiamate, imposta la concorrenza riservata alla funzione su «0immediate» per limitare tutte le chiamate alla funzione mentre aggiorni 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 API aggiornamenti interni possono essere incompatibili con le versioni precedenti e portare a conseguenze indesiderate, come errori di chiamata se la funzione dipende da questi aggiornamenti non pubblici. APIs Vedi il riferimento per un elenco di quelli disponibili al pubblico. API 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?.