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à.
Definire il gestore di funzioni Lambda in TypeScript
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 TypeScript, incluse le opzioni per la configurazione del progetto, le convenzioni di denominazione e le best practice. Questa pagina include anche un esempio di funzione TypeScript Lambda che acquisisce informazioni su un ordine, produce una ricevuta in un file di testo e lo inserisce in un bucket Amazon Simple Storage Service (Amazon S3). Per informazioni su come distribuire una funzione dopo averla scritta, consulta o. Distribuisci TypeScript codice transpilato in Lambda con archivi di file .zip Implementa codice trascritto TypeScript in Lambda con immagini di container
Configurazione del progetto TypeScript
Utilizzate un ambiente di sviluppo integrato locale (IDE) o un editor di testo per scrivere il codice TypeScript della funzione. Non puoi creare TypeScript codice sulla console Lambda.
Esistono diversi modi per inizializzare un progetto TypeScript Lambda. Ad esempio, puoi creare un progetto utilizzandonpm, creare un'AWS SAM applicazione o creare un'AWS CDK applicazione. Per creare il progetto utilizzandonpm:
npm init
Il codice della funzione risiede in un .ts file, che viene convertito in un JavaScript file in fase di compilazione. Puoi usare esbuild tsc) di Microsoft per trasporre il codice in. TypeScript JavaScript Per usare esbuild, aggiungilo come dipendenza di sviluppo:
npm install -D esbuild
Un tipico progetto di funzione TypeScript Lambda segue questa struttura generale:
/project-root ├── index.ts - Contains main handler ├── dist/ - Contains compiled JavaScript ├── package.json - Project metadata and dependencies ├── package-lock.json - Dependency lock file ├── tsconfig.json - TypeScript configuration └── node_modules/ - Installed dependencies
Esempio di codice della TypeScript funzione Lambda
Il seguente codice di funzione Lambda di esempio acquisisce informazioni su un ordine, produce una ricevuta in un file di testo e inserisce questo file in un bucket Amazon S3. Questo esempio definisce un tipo di evento personalizzato (). OrderEvent Per informazioni su come importare le definizioni dei tipi per le sorgenti di AWS eventi, consulta Definizioni dei tipi per Lambda.
Nota
Questo esempio utilizza un gestore di moduli ES. Lambda supporta sia il modulo ES che i gestori CommonJS. Per ulteriori informazioni, consulta Moduli CommonJS ed ES.
Esempio index.ts, funzione Lambda
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'; // Initialize the S3 client outside the handler for reuse const s3Client = new S3Client(); // Define the shape of the input event type OrderEvent = { order_id: string; amount: number; item: string; } /** * Lambda handler for processing orders and storing receipts in S3. */ export const handler = async (event: OrderEvent): Promise<string> => { try { // Access environment variables const bucketName = process.env.RECEIPT_BUCKET; if (!bucketName) { throw new Error('RECEIPT_BUCKET environment variable is not set'); } // Create the receipt content and key destination const receiptContent = `OrderID: ${event.order_id}\nAmount: $${event.amount.toFixed(2)}\nItem: ${event.item}`; const key = `receipts/${event.order_id}.txt`; // Upload the receipt to S3 await uploadReceiptToS3(bucketName, key, receiptContent); console.log(`Successfully processed order ${event.order_id} and stored receipt in S3 bucket ${bucketName}`); return 'Success'; } catch (error) { console.error(`Failed to process order: ${error instanceof Error ? error.message : 'Unknown error'}`); throw error; } }; /** * Helper function to upload receipt to S3 */ async function uploadReceiptToS3(bucketName: string, key: string, receiptContent: string): Promise<void> { try { const command = new PutObjectCommand({ Bucket: bucketName, Key: key, Body: receiptContent }); await s3Client.send(command); } catch (error) { throw new Error(`Failed to upload receipt to S3: ${error instanceof Error ? error.message : 'Unknown error'}`); } }
Questo file index.ts contiene le sezioni seguenti:
-
Blocco
import: utilizza questo blocco per includere le librerie richieste dalla funzione Lambda, come i client SDK AWS. -
const s3Clientdichiarazione: inizializza un client https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/ Amazon S3 al di fuori della funzione handler. Ciò fa sì che Lambda esegua questo codice durante la fase di inizializzazione e il client viene preservato per essere riutilizzato in più invocazioni. -
type OrderEvent: definisce la struttura dell'evento di input previsto. -
export const handler: Questa è la principale funzione di gestione richiamata da Lambda. Quando distribuisci la tua funzione, specificaindex.handlerla proprietà Handler. https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-Handler Il valore dellaHandlerproprietà è il nome del file e il nome del metodo del gestore esportato, separati da un punto. -
uploadReceiptToS3function: Questa è una funzione di supporto a cui fa riferimento la funzione principale del gestore.
Affinché questa funzione funzioni correttamente, il suo ruolo di esecuzione deve consentire l'azione. s3:PutObject Inoltre, assicuratevi di definire la variabile di RECEIPT_BUCKET ambiente. Dopo una chiamata riuscita, il bucket Amazon S3 dovrebbe contenere un file di ricevuta.
Moduli CommonJS ed ES
Node.js supporta due sistemi di moduli: moduli CommonJS ed ECMAScript (moduli ES). Lambda consiglia di utilizzare i moduli ES in quanto supporta l'attesa di primo livello, che consente il completamento di attività asincrone durante l'inizializzazione dell'ambiente di esecuzione. Node.js inizializzazione
Node.js tratta i file con estensione come moduli CommonJS mentre un'.cjsestensione indica i moduli ES. .mjs Per impostazione predefinita, Node.js tratta i file con estensione come moduli .js CommonJS. È possibile Node.js configurare il trattamento .js dei file come moduli ES specificando l'typeas module nel file della funzione. package.json È possibile configurare Node.js in Lambda per rilevare automaticamente se un .js file deve essere trattato come CommonJS o come modulo ES aggiungendo il —experimental-detect-module flag alla variabile di ambiente. NODE_OPTIONS Per ulteriori informazioni, consulta Funzionalità sperimentali Node.js .
Gli esempi seguenti mostrano i gestori di funzioni scritti utilizzando sia i moduli ES che i moduli CommonJS. Gli esempi rimanenti in questa pagina utilizzano tutti moduli ES.
Node.js inizializzazione
Node.js utilizza un I/O modello non bloccante che supporta operazioni asincrone efficienti utilizzando un ciclo di eventi. Ad esempio, se Node.js effettua una chiamata di rete, la funzione continua a elaborare altre operazioni senza bloccare una risposta di rete. Quando la risposta di rete viene ricevuta, viene inserita nella coda di callback. Le attività della coda vengono elaborate al termine dell'attività corrente.
Lambda consiglia di utilizzare await di primo livello in modo che le attività asincrone avviate durante l'inizializzazione dell'ambiente di esecuzione vengano completate durante l'inizializzazione. Le attività asincrone che non vengono completate durante l'inizializzazione vengono in genere eseguite durante la prima chiamata di funzione. Ciò può causare comportamenti o errori imprevisti.
Ad esempio, l'inizializzazione della funzione potrebbe effettuare una chiamata di rete per recuperare un AWS parametro da Parameter Store. Se questa attività non viene completata durante l'inizializzazione, il valore potrebbe essere nullo durante una chiamata. Può inoltre verificarsi un ritardo tra l'inizializzazione e l'invoke, che può causare errori nelle operazioni sensibili al fattore tempo. In particolare, le chiamate AWS di assistenza possono basarsi su firme di richieste sensibili al fattore tempo, con conseguenti errori delle chiamate di servizio se la chiamata non viene completata durante la fase di inizializzazione.
Il completamento delle attività durante l'inizializzazione in genere migliora le prestazioni di avvio a freddo e le richiama innanzitutto quando si utilizza Provisioned Concurrency. Per ulteriori informazioni, consulta il nostro post sul blog Using Node.js ES modules and top-level await in. AWS Lambda
Convenzioni di denominazione dei gestori
Quando si configura una funzione, il valore dell'impostazione Handler è il nome del file e il nome del metodo handler esportato, separati da un punto. L'impostazione predefinita per le funzioni create nella console e negli esempi in questa guida è index.handler. Questo indica il metodo handler che viene esportato dal file index.js o index.mjs.
Se si crea una funzione nella console utilizzando un nome di file o un nome del gestore di funzione diverso, è necessario modificare il nome del gestore predefinito.
Modifica del nome del gestore funzioni (console)
-
Apri la pagina Funzioni
della console Lambda e scegli la tua funzione. -
Scegli la scheda Codice.
-
Scorri verso il basso fino al riquadro Impostazioni di runtime e scegli Modifica.
-
In Gestore, inserisci il nuovo nome per il tuo gestore di funzioni.
-
Scegli Save (Salva).
Definizione e accesso all'oggetto evento di input
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" }
Quando si lavora con le funzioni Lambda in TypeScript, è possibile definire la forma dell'evento di input utilizzando un tipo o un'interfaccia. In questo esempio, definiamo la struttura dell'evento utilizzando un tipo:
type OrderEvent = {
order_id: string;
amount: number;
item: string;
}
Dopo aver definito il tipo o l'interfaccia, utilizzateli nella firma del gestore per garantire la sicurezza del tipo:
export const handler = async (event: OrderEvent): Promise<string> => {
Durante la compilazione, TypeScript verifica che l'oggetto evento contenga i campi obbligatori con i tipi corretti. Ad esempio, il TypeScript compilatore segnala un errore se si tenta di utilizzarlo event.order_id come numero o event.amount come stringa.
Schemi di gestione validi per le funzioni TypeScript
Si consiglia di utilizzare async/await per dichiarare il gestore della funzione invece di utilizzare i callback. https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/using-a-callback-function.html Async/await è un modo conciso e leggibile per scrivere codice asincrono, senza la necessità di callback annidati o di concatenare promesse. Con async/await, puoi scrivere codice che si legge come codice sincrono, pur essendo asincrono e non bloccante.
Gli esempi in questa sezione utilizzano il tipo S3Event. Tuttavia, puoi utilizzare qualsiasi altro tipo di AWS evento nel pacchetto
-
Aggiungi il @types/aws-lambda pacchetto come dipendenza di sviluppo:
npm install -D @types/aws-lambda -
Importa i tipi di cui hai bisogno, ad esempio
ContextS3Event, oCallback.
gestori di funzioni asincrone (consigliati)
La parola chiave async contrassegna una funzione come asincrona, mentre la parola chiave await mette in pausa l'esecuzione della funzione fino alla risoluzione di Promise. Il gestore accetta i seguenti argomenti:
-
event: contiene i dati di input passati alla funzione. -
context: contiene informazioni sull'invocazione, sulla funzione e sull'ambiente di esecuzione. Per ulteriori informazioni, consulta Utilizzo dell'oggetto contestuale Lambda per recuperare informazioni TypeScript sulla funzione.
Ecco le firme valide per il async/await pattern:
export const handler = async(event: S3Event): Promise<void> => { };
export const handler = async(event: S3Event, context: Context): Promise<void> => { };
Nota
Quando elabori matrici di elementi in modo asincrono, assicurati di utilizzare await with Promise.all per garantire il completamento di tutte le operazioni. Metodi come forEach non aspettare il completamento dei callback asincroni. Per ulteriori informazioni, consulta Array.prototype.forEach ()
Gestori di funzioni sincroni
Se la funzione non esegue alcuna attività asincrona, è possibile utilizzare un gestore di funzioni sincrone, utilizzando una delle seguenti firme di funzione:
export const handler = (event: S3Event): void => { };
export const handler = (event: S3Event, context: Context): void => { };
gestori di funzioni di streaming delle risposte
Lambda supporta lo streaming di risposte con. Node.js I gestori delle funzioni di streaming delle risposte utilizzano il decoratore AWSLambda.streamifyResponse () e accettano 3 parametri: event, responseStream e context. La firma della funzione è:
export const handler = awslambda.streamifyResponse(async (event: APIGatewayProxyEvent, responseStream: NodeJS.WritableStream, context: Context) => { });
Per ulteriori informazioni, consulta Response streaming for Lambda functions.
Callback-based gestori di funzioni
Nota
Callback-based i gestori di funzioni sono supportati solo fino a 22. Node.js A partire da Node.js 24, le attività asincrone dovrebbero essere implementate utilizzando gestori di funzioni asincroni.
Callback-based i gestori di funzioni possono utilizzare gli argomenti event, context e callback. L'argomento callback prevede una Error e una risposta, che deve essere. JSON-serializable
Ecco la firma valida per il pattern del callback handler:
export const handler =(event: S3Event, context: Context, callback: Callback<void>): void => { };
La funzione continua a essere eseguita fino a quando il ciclo di eventi non
Esempio TypeScript funzione con callback
L'esempio seguente utilizzaAPIGatewayProxyCallback, che è un tipo di callback specializzato specifico per le integrazioni di API Gateway. La maggior parte delle fonti di AWS eventi utilizza il Callback tipo generico mostrato nelle firme precedenti.
import { Context, APIGatewayProxyCallback, APIGatewayEvent } from 'aws-lambda'; export const lambdaHandler = (event: APIGatewayEvent, context: Context, callback: APIGatewayProxyCallback): void => { console.log(`Event: ${JSON.stringify(event, null, 2)}`); console.log(`Context: ${JSON.stringify(context, null, 2)}`); callback(null, { statusCode: 200, body: JSON.stringify({ message: 'hello world', }), }); };
Utilizzo dell'SDK per la JavaScript v3 nel gestore
Spesso, utilizzerai le funzioni Lambda per interagire o apportare aggiornamenti ad altre AWS risorse. Il modo più semplice per interfacciarsi con queste risorse è usare la AWS SDK per JavaScript. Tutti i Node.js runtime Lambda supportati includono l'SDK per la versione 3. JavaScript Tuttavia, ti consigliamo vivamente di includere i client AWS SDK di cui hai bisogno nel tuo pacchetto di distribuzione. Ciò massimizza la compatibilità con le versioni precedenti durante i futuri aggiornamenti del runtime di Lambda.
Per aggiungere dipendenze SDK alla tua funzione, usa il npm install comando per i client SDK specifici di cui hai bisogno. Nel codice di esempio, abbiamo utilizzato il client Amazon S3. Aggiungi queste dipendenze eseguendo i seguenti comandi nella directory che contiene il file package.json:
npm install @aws-sdk/client-s3
Nel codice della funzione, importate il client e i comandi necessari, come dimostra la funzione di esempio:
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
Quindi, inizializza un client Amazon S3:
const s3Client = new S3Client();
In questo esempio, abbiamo inizializzato il nostro client Amazon S3 all’esterno della funzione del gestore principale per evitare di doverlo inizializzare ogni volta che invochiamo la nostra funzione. Dopo aver inizializzato il client SDK, puoi utilizzarlo per effettuare chiamate API per quel servizio. AWS Il codice di esempio richiama l'azione PutObject API Amazon S3 nel modo seguente:
const command = new PutObjectCommand({
Bucket: bucketName,
Key: key,
Body: receiptContent
});
Accesso alle variabili d'ambiente
Nel codice del gestore, puoi fare riferimento a qualsiasi variabile di ambiente utilizzando. process.env In questo esempio, facciamo riferimento alla variabile di ambiente RECEIPT_BUCKET definita utilizzando le seguenti righe di codice:
// Access environment variables const bucketName = process.env.RECEIPT_BUCKET; if (!bucketName) { throw new Error('RECEIPT_BUCKET environment variable is not set'); }
Utilizzo dello stato globale
Lambda esegue il codice statico durante la fase di inizializzazione prima di richiamare la funzione per la prima volta. Le risorse create durante l'inizializzazione restano in memoria tra le invocazioni, in modo da evitare di doverle creare ogni volta che si invoca la funzione.
Nel codice di esempio, il codice di inizializzazione del client S3 è esterno al gestore. Il runtime inizializza il client prima che la funzione gestisca il primo evento e il client rimane disponibile per il riutilizzo in tutte le chiamate.
Procedure consigliate per il codice per le funzioni Lambda TypeScript
Segui queste linee guida quando crei funzioni Lambda:
-
Separare il gestore Lambda dalla logica principale. In questo modo è possibile creare una funzione di cui è più semplice eseguire l'unit test.
-
Controllare le dipendenze nel pacchetto di distribuzione della funzione. L'ambiente di AWS Lambda esecuzione contiene una serie di librerie. Per i runtime di Python Node.js e Python, questi includono gli AWS SDK. Per abilitare il set di caratteristiche e aggiornamenti della sicurezza più recenti, Lambda aggiorna periodicamente tali librerie. Tali aggiornamenti possono introdurre lievi modifiche al comportamento della funzione Lambda. Per mantenere il controllo completo delle dipendenze utilizzate dalla funzione, inserire tutte le dipendenze nel pacchetto di implementazione.
-
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. 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, vedi Riutilizzo delle connessioni con in. Keep-Alive 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 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 API non documentate e non pubbliche nel codice della funzione Lambda. Per i runtime AWS Lambda gestiti, Lambda applica periodicamente aggiornamenti di sicurezza e funzionali alle API interne di Lambda. Questi aggiornamenti API interni potrebbero essere incompatibili con le versioni precedenti, causando conseguenze indesiderate come errori di chiamata se la funzione ha una dipendenza su queste API non pubbliche. Consulta il riferimento all'API per un elenco di API disponibili pubblicamente.
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?