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 C#
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.
Quando la funzione viene richiamata e Lambda esegue il metodo del gestore della funzione, passa due argomenti alla funzione. Il primo argomento è l'oggetto event
. Quando un altro Servizio AWS richiama la funzione, l'event
oggetto contiene dati sull'evento che ha causato l'invocazione della funzione. Ad esempio, un event
oggetto di API Gateway contiene informazioni sul percorso, sul HTTP metodo e sulle intestazioni. HTTP L'esatta struttura degli eventi varia in base alla funzione che Servizio AWS richiama la funzione. Per ulteriori informazioni sui formati degli eventi per i singoli servizi, consulta Richiamare Lambda con eventi di altri servizi AWS.
Lambda passa alla funzione anche un oggetto context
. Questo oggetto di contesto contiene informazioni sull'invocazione, sulla funzione e sull'ambiente di esecuzione. Per ulteriori informazioni, consulta Utilizzo dell'oggetto contesto Lambda per recuperare informazioni sulla funzione C#.
Il formato nativo per tutti gli eventi Lambda è costituito da flussi di byte che rappresentano l'evento formattato. JSON Se i parametri di input e output della funzione non sono di tipo System.IO.Stream
, è necessario serializzarli. Specifica il serializzatore che desideri utilizzare impostando l'attributo assembly LambdaSerializer
. Per ulteriori informazioni, consulta Serializzazione nelle funzioni Lambda.
Argomenti
- . NETmodelli di esecuzione per Lambda
- Gestori di librerie di classi
- Gestori di assembly eseguibili
- Serializzazione nelle funzioni Lambda
- Semplificazione del codice delle funzioni con il framework Lambda Annotations
- Restrizioni del gestore della funzione Lambda
- Procedure consigliate per le funzioni Lambda in C#
. NETmodelli di esecuzione per Lambda
Esistono due diversi modelli di esecuzione per l'esecuzione delle funzioni Lambda. NET: l'approccio alla libreria di classi e l'approccio all'assemblaggio eseguibile.
Nell'approccio alla libreria di classi, fornisci a Lambda una stringa che indica AssemblyName
, ClassName
e Method
della funzione da richiamare. Per ulteriori informazioni sul formato di questa stringa, consulta Gestori di librerie di classi. Durante la fase di inizializzazione della funzione, la classe della funzione viene inizializzata e viene eseguito qualsiasi codice nel costruttore.
Nell'approccio di assembly eseguibile, si utilizza la funzionalità delle istruzioni di livello superiore
Le sezioni seguenti forniscono esempi di codice di funzione per questi due approcci.
Gestori di librerie di classi
Il seguente codice di funzione Lambda mostra un esempio di metodo handler (FunctionHandler
) per una funzione Lambda che utilizza l'approccio della libreria di classi. In questo esempio funtion, Lambda riceve un evento API da Gateway che richiama la funzione. La funzione legge un record da un database e restituisce il record come parte della risposta Gateway. API
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] namespace GetProductHandler; public class Function { private readonly IDatabaseRepository _repo; public Function() { this._repo = new DatabaseRepository(); } public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest request) { var id = request.PathParameters["id"]; var databaseRecord = await this._repo.GetById(id); return new APIGatewayProxyResponse { StatusCode = (int)HttpStatusCode.OK, Body = JsonSerializer.Serialize(databaseRecord) }; } }
Quando crei una funzione Lambda, devi fornire a Lambda informazioni sul gestore della funzione sotto forma di stringa del gestore. Questo indica a Lambda quale metodo del codice eseguire quando la funzione viene richiamata. In C#, il formato della stringa del gestore quando si utilizza l'approccio della libreria di classi è il seguente:
ASSEMBLY::TYPE::METHOD
, dove:
-
ASSEMBLY
è il nome di. NETfile di assemblaggio per l'applicazione. Se si utilizza ilAmazon.Lambda.Tools
CLI per creare l'applicazione e non si imposta il nome dell'assembly utilizzando laAssemblyName
proprietà nel file.csproj, siASSEMBLY
tratta semplicemente del nome del file .csproj. -
TYPE
è il nome completo del tipo di gestore, costituito daNamespace
eClassName
. -
METHOD
è il nome del metodo del gestore della funzione nel codice.
Per il codice di esempio mostrato, se l'assembly è denominato GetProductHandler
, la stringa del gestore sarebbe GetProductHandler::GetProductHandler.Function::FunctionHandler
.
Gestori di assembly eseguibili
Nell'esempio seguente, la funzione Lambda è definita come un assembly eseguibile. Il metodo handler in questo codice è denominato Handler
. Quando si utilizzano assembly eseguibili, è necessario avviare il runtime Lambda. Per far ciò, viene utilizzato il metodo LambdaBootstrapBuilder.Create
. Questo metodo accetta come input il metodo utilizzato dalla funzione come gestore e il serializzatore Lambda da utilizzare.
Per ulteriori informazioni sull'utilizzo delle istruzioni di primo livello, vedere Introduzione al. NET6 runtime per AWS Lambda
namespace GetProductHandler; IDatabaseRepository repo = new DatabaseRepository(); await LambdaBootstrapBuilder.Create<APIGatewayProxyRequest>(Handler, new DefaultLambdaJsonSerializer()) .Build() .RunAsync(); async Task<APIGatewayProxyResponse> Handler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context) { var id = apigProxyEvent.PathParameters["id"]; var databaseRecord = await this.repo.GetById(id); return new APIGatewayProxyResponse { StatusCode = (int)HttpStatusCode.OK, Body = JsonSerializer.Serialize(databaseRecord) }; };
Quando si utilizzano assembly eseguibili, la stringa del gestore che indica a Lambda come eseguire il codice è il nome dell'assembly. In questo esempio, sarebbe GetProductHandler
.
Serializzazione nelle funzioni Lambda
Se la funzione Lambda utilizza i tipi di input/output diversi da un oggetto Stream
, è necessario aggiungere una libreria di serializzazione all'applicazione. È possibile implementare la serializzazione utilizzando la serializzazione standard basata sulla riflessione fornita da System.Text.Json
e Newtonsoft.Json
oppure utilizzando la serializzazione generata dal codice sorgente
Utilizzo della serializzazione generata dal codice sorgente
La serializzazione generata dal codice sorgente è una funzionalità di. NETversioni 6 e successive che consentono la generazione del codice di serializzazione in fase di compilazione. Elimina la necessità di riflessione e può migliorare le prestazioni della tua funzione. Per utilizzare la serializzazione generata dal codice sorgente nella tua funzione, procedi come segue:
-
Crea una nuova classe parziale che eredita da
JsonSerializerContext
, aggiungendo attributiJsonSerializable
per tutti i tipi che richiedono la serializzazione o la deserializzazione. -
Configura il
LambdaSerializer
per utilizzare unSourceGeneratorLambdaJsonSerializer<T>
. -
Aggiorna qualsiasi serializzazione o deserializzazione manuale nel codice dell'applicazione per utilizzare la classe appena creata.
Nel codice seguente viene illustrata una funzione di esempio che utilizza la serializzazione generata dal codice sorgente.
[assembly: LambdaSerializer(typeof(SourceGeneratorLambdaJsonSerializer<CustomSerializer>))] public class Function { private readonly IDatabaseRepository _repo; public Function() { this._repo = new DatabaseRepository(); } public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest request) { var id = request.PathParameters["id"]; var databaseRecord = await this._repo.GetById(id); return new APIGatewayProxyResponse { StatusCode = (int)HttpStatusCode.OK, Body = JsonSerializer.Serialize(databaseRecord, CustomSerializer.Default.Product) }; } } [JsonSerializable(typeof(APIGatewayProxyRequest))] [JsonSerializable(typeof(APIGatewayProxyResponse))] [JsonSerializable(typeof(Product))] public partial class CustomSerializer : JsonSerializerContext { }
Nota
Se desideri utilizzare la compilazione anticipata nativa (AOT) con Lambda, devi utilizzare la serializzazione generata dal codice sorgente.
Utilizzo della serializzazione basata sulla riflessione
AWS fornisce librerie predefinite che consentono di aggiungere rapidamente la serializzazione all'applicazione. È possibile configurarlo utilizzando i pacchetti Amazon.Lambda.Serialization.SystemTextJson
o Amazon.Lambda.Serialization.Json
NuGet . Dietro le quinte, Amazon.Lambda.Serialization.SystemTextJson
utilizza System.Text.Json
per eseguire attività di serializzazione e Amazon.Lambda.Serialization.Json
utilizza il pacchetto Newtonsoft.Json
.
È possibile inoltre creare una libreria di serializzazione personalizzata implementando l'interfaccia ILambdaSerializer
, disponibile come parte della libreria Amazon.Lambda.Core
. L'interfaccia definisce due metodi:
-
T Deserialize<T>(Stream requestStream);
Implementate questo metodo per deserializzare il payload della richiesta dall'
Invoke
APIinterno all'oggetto che viene passato al gestore della funzione Lambda. -
T Serialize<T>(T response, Stream responseStream);
Implementate questo metodo per serializzare il risultato restituito dal gestore della funzione Lambda nel payload di risposta restituito dall'operazione.
Invoke
API
Semplificazione del codice delle funzioni con il framework Lambda Annotations
Lambda Annotations è un framework per. NET6 e. NET8 che semplifica la scrittura di funzioni Lambda usando C#. Con il framework Annotations, è possibile sostituire gran parte del codice in una funzione Lambda scritta utilizzando il normale modello di programmazione. Il codice scritto utilizzando il framework utilizza espressioni più semplici che consentono di concentrarsi sulla logica aziendale.
Il codice di esempio riportato di seguito mostra come l'utilizzo del framework delle annotazioni può semplificare la scrittura di funzioni Lambda. Il primo esempio mostra il codice scritto utilizzando il normale modello di programmazione Lambda e il secondo mostra l'equivalente utilizzando il framework Annotations.
public APIGatewayHttpApiV2ProxyResponse LambdaMathAdd(APIGatewayHttpApiV2ProxyRequest request, ILambdaContext context) { if (!request.PathParameters.TryGetValue("x", out var xs)) { return new APIGatewayHttpApiV2ProxyResponse { StatusCode = (int)HttpStatusCode.BadRequest }; } if (!request.PathParameters.TryGetValue("y", out var ys)) { return new APIGatewayHttpApiV2ProxyResponse { StatusCode = (int)HttpStatusCode.BadRequest }; } var x = int.Parse(xs); var y = int.Parse(ys); return new APIGatewayHttpApiV2ProxyResponse { StatusCode = (int)HttpStatusCode.OK, Body = (x + y).ToString(), Headers = new Dictionary≪string, string> { { "Content-Type", "text/plain" } } }; }
[LambdaFunction] [HttpApi(LambdaHttpMethod.Get, "/add/{x}/{y}")] public int Add(int x, int y) { return x + y; }
Per un altro esempio di come l'utilizzo di Lambda Annotations può semplificare il codice, consulta questo esempio di applicazione cross-serviceawsdocs/aws-doc-sdk-examples
GitHub La cartella PamApiAnnotations
utilizza Lambda Annotations nel file function.cs
principale. Per fare un confronto, la cartella PamApi
contiene file equivalenti scritti utilizzando il normale modello di programmazione Lambda.
Il framework Annotations utilizza generatori di codice sorgente
Per ulteriori informazioni su come utilizzare Lambda Annotations for. NET, consulta le seguenti risorse:
-
Il
aws/aws-lambda-dotnet
GitHub repository. -
Presentazione. NETAnnotations Lambda Framework (anteprima
) sul blog Developer AWS Tools. -
Il
Amazon.Lambda.Annotations
NuGet pacchetto.
Iniezione delle dipendenze con il framework Lambda Annotations
Puoi utilizzare il framework Lambda Annotations anche per aggiungere l'iniezione di dipendenze alle tue funzioni Lambda utilizzando una sintassi che conosci. Quando aggiungi un attributo [LambdaStartup]
a un file Startup.cs
, il framework Lambda Annotations genererà il codice richiesto in fase di compilazione.
[LambdaStartup] public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddSingleton<IDatabaseRepository, DatabaseRepository>(); } }
La tua funzione Lambda può iniettare servizi utilizzando l'iniezione del costruttore o iniettandoli in metodi individuali utilizzando l'attributo [FromServices]
.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] namespace GetProductHandler; public class Function { private readonly IDatabaseRepository _repo; public Function(IDatabaseRepository repo) { this._repo = repo; } [LambdaFunction] [HttpApi(LambdaHttpMethod.Get, "/product/{id}")] public async Task<Product> FunctionHandler([FromServices] IDatabaseRepository repository, string id) { return await this._repo.GetById(id); } }
Restrizioni del gestore della funzione Lambda
Tieni in considerazione che la firma del gestore presenta alcune restrizioni.
-
Nella firma del gestore non è possibile utilizzare
unsafe
e tipi di puntatori. Tuttavia, il contestounsafe
può essere utilizzato nel metodo del gestore e nelle relative dipendenze. Per ulteriori informazioni, consulta unsafe (Riferimenti per C#)sul sito web Microsoft Docs. -
Non può passare un numero variabile di parametri utilizzando la parola chiave
params
o utilizzareArgIterator
come parametro di input o di restituzione per supportare un numero variabile di parametri. -
Il gestore potrebbe non essere un metodo generico, ad esempio IList <T>Sort <T>(IList<T>input).
-
I gestori asincroni con firma
async void
non sono supportati.
Procedure consigliate per le funzioni Lambda in C#
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.
-
Controllare le dipendenze nel pacchetto di distribuzione della funzione. L'ambiente di AWS Lambda esecuzione contiene diverse librerie. 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. Per le funzioni create in. NET, evita di caricare l'intera AWS SDK libreria come parte del pacchetto di distribuzione. Dipendi invece in modo selettivo dai moduli che raccolgono i componenti di cui SDK hai bisogno (ad esempio DynamoDB, moduli Amazon SDK S3 e librerie di base Lambda).
-
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 gli asset statici 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 «
0
immediate» 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?
.