Tentukan penangan fungsi Lambda di C # - AWS Lambda

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Tentukan penangan fungsi Lambda di C #

Handler fungsi Lambda Anda adalah metode dalam kode fungsi Anda yang memproses peristiwa. Saat fungsi Anda diaktifkan, Lambda menjalankan metode handler. Fungsi Anda berjalan sampai handler mengembalikan respons, keluar, atau waktu habis.

Ketika fungsi Anda dipanggil dan Lambda menjalankan metode handler fungsi Anda, ia meneruskan dua argumen ke fungsi Anda. Argumen pertama adalah event objek. Ketika yang lain Layanan AWS memanggil fungsi Anda, event objek berisi data tentang peristiwa yang menyebabkan fungsi Anda dipanggil. Misalnya, event objek dari API Gateway berisi informasi tentang jalur, HTTP metode, dan HTTP header. Struktur acara yang tepat bervariasi sesuai dengan Layanan AWS pemanggilan fungsi Anda. Lihat Memanggil Lambda dengan acara dari layanan lain AWS untuk informasi selengkapnya tentang format acara untuk layanan individual.

Lambda juga meneruskan context objek ke fungsi Anda. Objek ini berisi informasi tentang pemanggilan, fungsi, dan lingkungan eksekusi. Untuk informasi selengkapnya, lihat Menggunakan objek konteks Lambda untuk mengambil informasi fungsi C #.

Format asli untuk semua peristiwa Lambda adalah aliran byte yang mewakili peristiwa yang diformat. JSON Kecuali parameter input dan output fungsi Anda bertipeSystem.IO.Stream, Anda harus membuat serialisasi. Tentukan serializer yang ingin Anda gunakan dengan mengatur atribut LambdaSerializer assembly. Untuk informasi selengkapnya, lihat Serialisasi dalam fungsi Lambda.

. NETmodel eksekusi untuk Lambda

Ada dua model eksekusi yang berbeda untuk menjalankan fungsi Lambda di. NET: pendekatan perpustakaan kelas dan pendekatan perakitan yang dapat dieksekusi.

Dalam pendekatan pustaka kelas, Anda memberikan Lambda string yang menunjukkanAssemblyName,ClassName, dan Method fungsi yang akan dipanggil. Untuk informasi selengkapnya tentang format string ini, lihatPenangan perpustakaan kelas. Selama fase inisialisasi fungsi, kelas fungsi Anda diinisialisasi, dan kode apa pun dalam konstruktor dijalankan.

Dalam pendekatan perakitan yang dapat dieksekusi, Anda menggunakan fitur pernyataan tingkat atas C # 9. Pendekatan ini menghasilkan perakitan yang dapat dieksekusi yang dijalankan Lambda setiap kali menerima perintah pemanggilan untuk fungsi Anda. Anda hanya memberi Lambda nama rakitan yang dapat dieksekusi untuk dijalankan.

Bagian berikut memberikan contoh kode fungsi untuk dua pendekatan ini.

Penangan perpustakaan kelas

Kode fungsi Lambda berikut menunjukkan contoh metode handler (FunctionHandler) untuk fungsi Lambda yang menggunakan pendekatan pustaka kelas. Dalam contoh funtion ini, Lambda menerima peristiwa API dari Gateway yang memanggil fungsi. Fungsi membaca catatan dari database dan mengembalikan catatan sebagai bagian dari respons API Gateway.

[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) }; } }

Saat Anda membuat fungsi Lambda, Anda perlu memberikan Lambda informasi tentang handler fungsi Anda dalam bentuk string handler. Ini memberi tahu Lambda metode mana dalam kode Anda untuk dijalankan ketika fungsi Anda dipanggil. Dalam C #, format string handler saat menggunakan pendekatan perpustakaan kelas adalah sebagai berikut:

ASSEMBLY::TYPE::METHOD, dimana:

  • ASSEMBLYadalah nama dari. NETfile perakitan untuk aplikasi Anda. Jika Anda menggunakan Amazon.Lambda.Tools CLI untuk membangun aplikasi Anda dan Anda tidak mengatur nama assembly menggunakan AssemblyName properti di file.csproj, maka ASSEMBLY hanya nama file.csproj Anda.

  • TYPEadalah nama lengkap dari tipe handler, yang terdiri dari Namespace dan. ClassName

  • METHODadalah nama metode fungsi handler dalam kode Anda.

Untuk contoh kode yang ditampilkan, jika perakitan diberi namaGetProductHandler, maka string handler akan menjadiGetProductHandler::GetProductHandler.Function::FunctionHandler.

Penangan perakitan yang dapat dieksekusi

Dalam contoh berikut, fungsi Lambda didefinisikan sebagai perakitan yang dapat dieksekusi. Metode handler dalam kode ini Handler dinamai. Saat menggunakan rakitan yang dapat dieksekusi, runtime Lambda harus di-bootstrap. Untuk melakukan ini, Anda menggunakan LambdaBootstrapBuilder.Create metode ini. Metode ini mengambil sebagai input metode yang digunakan fungsi Anda sebagai handler dan serializer Lambda untuk digunakan.

Untuk informasi selengkapnya tentang menggunakan pernyataan tingkat atas, lihat Memperkenalkan. NET6 runtime untuk AWS Lambda di blog AWS komputasi.

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) }; };

Saat menggunakan rakitan yang dapat dieksekusi, string handler yang memberi tahu Lambda cara menjalankan kode Anda adalah nama perakitan. Dalam contoh ini, itu akan menjadiGetProductHandler.

Serialisasi dalam fungsi Lambda

Jika fungsi Lambda Anda menggunakan jenis input atau output selain Stream objek, Anda harus menambahkan pustaka serialisasi ke aplikasi Anda. Anda dapat menerapkan serialisasi baik menggunakan serialisasi berbasis refleksi standar yang disediakan oleh System.Text.Json danNewtonsoft.Json, atau dengan menggunakan serialisasi yang dihasilkan sumber.

Menggunakan serialisasi yang dihasilkan sumber

Serialisasi yang dihasilkan sumber adalah fitur dari. NETversi 6 dan yang lebih baru yang memungkinkan kode serialisasi dihasilkan pada waktu kompilasi. Ini menghilangkan kebutuhan untuk refleksi dan dapat meningkatkan kinerja fungsi Anda. Untuk menggunakan serialisasi yang dihasilkan sumber dalam fungsi Anda, lakukan hal berikut:

  • Buat kelas parsi baru yang mewarisi dariJsonSerializerContext, menambahkan JsonSerializable atribut untuk semua jenis yang memerlukan serialisasi atau deserialisasi.

  • Konfigurasikan LambdaSerializer untuk menggunakan aSourceGeneratorLambdaJsonSerializer<T>.

  • Perbarui serialisasi manual atau deserialisasi apa pun dalam kode aplikasi Anda untuk menggunakan kelas yang baru dibuat.

Sebuah fungsi contoh menggunakan sumber yang dihasilkan serialisasi ditampilkan dalam kode berikut.

[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 { }
catatan

Jika Anda ingin menggunakan native sebelumnya compilation (AOT) dengan Lambda, Anda harus menggunakan serialisasi yang dihasilkan sumber.

Menggunakan serialisasi berbasis refleksi

AWS menyediakan pustaka bawaan untuk memungkinkan Anda menambahkan serialisasi ke aplikasi dengan cepat. Anda mengonfigurasi ini menggunakan Amazon.Lambda.Serialization.Json NuGet paket Amazon.Lambda.Serialization.SystemTextJson atau. Di belakang layar, Amazon.Lambda.Serialization.SystemTextJson gunakan System.Text.Json untuk melakukan tugas serialisasi, dan Amazon.Lambda.Serialization.Json menggunakan Newtonsoft.Json paket.

Anda juga dapat membuat pustaka serialisasi Anda sendiri dengan mengimplementasikan ILambdaSerializer antarmuka, yang tersedia sebagai bagian dari Amazon.Lambda.Core perpustakaan. Antarmuka ini mendefinisikan dua metode:

  • T Deserialize<T>(Stream requestStream);

    Anda menerapkan metode ini untuk deserialisasi payload permintaan dari objek ke objek yang diteruskan Invoke API ke penangan fungsi Lambda Anda.

  • T Serialize<T>(T response, Stream responseStream);

    Anda menerapkan metode ini untuk membuat serial hasil yang dikembalikan dari penangan fungsi Lambda Anda ke dalam payload respons yang dikembalikan operasi. Invoke API

Sederhanakan kode fungsi dengan kerangka kerja Anotasi Lambda

Anotasi Lambda adalah kerangka kerja untuk. NET6 dan. NET8 yang menyederhanakan penulisan fungsi Lambda menggunakan C #. Dengan kerangka kerja Anotasi, Anda dapat mengganti banyak kode dalam fungsi Lambda yang ditulis menggunakan model pemrograman biasa. Kode yang ditulis menggunakan kerangka kerja menggunakan ekspresi sederhana yang memungkinkan Anda untuk fokus pada logika bisnis Anda.

Contoh kode berikut menunjukkan bagaimana menggunakan kerangka anotasi dapat menyederhanakan penulisan fungsi Lambda. Contoh pertama menunjukkan kode yang ditulis menggunakan model program Lambda biasa, dan yang kedua menunjukkan yang setara menggunakan kerangka kerja Anotasi.

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

Untuk contoh lain bagaimana menggunakan Anotasi Lambda dapat menyederhanakan kode Anda, lihat contoh aplikasi lintas layanan ini di repositori. awsdocs/aws-doc-sdk-examples GitHub Folder PamApiAnnotations menggunakan Anotasi Lambda di file utama. function.cs Sebagai perbandingan, PamApi folder memiliki file setara yang ditulis menggunakan model pemrograman Lambda biasa.

Kerangka kerja Anotasi menggunakan generator sumber untuk menghasilkan kode yang diterjemahkan dari model pemrograman Lambda ke kode yang terlihat pada contoh kedua.

Untuk informasi selengkapnya tentang cara menggunakan Anotasi Lambda untuk. NET, lihat sumber daya berikut:

Injeksi ketergantungan dengan kerangka kerja Anotasi Lambda

Anda juga dapat menggunakan kerangka kerja Anotasi Lambda untuk menambahkan injeksi ketergantungan ke fungsi Lambda Anda menggunakan sintaks yang Anda kenal. Saat Anda menambahkan [LambdaStartup] atribut ke Startup.cs file, kerangka kerja Anotasi Lambda akan menghasilkan kode yang diperlukan pada waktu kompilasi.

[LambdaStartup] public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddSingleton<IDatabaseRepository, DatabaseRepository>(); } }

Fungsi Lambda Anda dapat menyuntikkan layanan menggunakan injeksi konstruktor atau dengan menyuntikkan ke dalam metode individual menggunakan atribut. [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); } }

Pembatasan handler fungsi Lambda

Perhatikan bahwa ada beberapa pembatasan pada tanda tangan handler.

  • Mungkin tidak unsafe dan menggunakan tipe pointer dalam tanda tangan handler, meskipun Anda dapat menggunakan unsafe konteks di dalam metode handler dan dependensinya. Untuk informasi selengkapnya, lihat unsafe (Referensi C#) di situs web Microsoft Docs.

  • Ini mungkin tidak melewati sejumlah variabel parameter menggunakan params kata kunci, atau digunakan ArgIterator sebagai input atau parameter pengembalian, yang digunakan untuk mendukung sejumlah variabel parameter.

  • Handler mungkin bukan metode generik, misalnya, IList <T>Sort <T>(IList<T>input).

  • Handler asinkron dengan tanda tangan async void tidak didukung.

Praktik terbaik kode untuk fungsi C# Lambda

Patuhi pedoman dalam daftar berikut untuk menggunakan praktik pengkodean terbaik saat membangun fungsi Lambda Anda:

  • Pisahkan handler Lambda dari logika inti Anda. Ini memungkinkan Anda untuk membuat fungsi yang lebih dapat teruji.

  • Kontrol dependensi dalam paket penerapan fungsi Anda. Lingkungan AWS Lambda eksekusi berisi sejumlah pustaka. Untuk mengaktifkan serangkaian fitur dan pembaruan keamanan terbaru, Lambda akan memperbarui pustaka ini secara berkala. Pembaruan ini dapat memberikan perubahan kecil pada perilaku fungsi Lambda Anda. Untuk memiliki kendali penuh atas dependensi yang digunakan fungsi Anda, kemas semua dependensi Anda dengan paket deployment Anda.

  • Minimalkan kompleksitas dependensi Anda. Utamakan memilih kerangka kerja lebih sederhana yang cepat dimuat dalam memulai lingkungan eksekusi.

  • Minimalkan ukuran paket penerapan Anda sesuai kebutuhan runtime-nya. Ini akan mengurangi jumlah waktu yang dibutuhkan untuk mengunduh dan membongkar paket deployment Anda sebelum invokasi. Untuk fungsi yang ditulis dalam. NET, hindari mengunggah seluruh AWS SDK perpustakaan sebagai bagian dari paket penerapan Anda. Sebagai gantinya, secara selektif bergantung pada modul yang mengambil komponen yang SDK Anda butuhkan (misalnya DynamoDB, modul Amazon SDK S3, dan pustaka inti Lambda).

  • Manfaatkan penggunaan kembali lingkungan eksekusi untuk meningkatkan kinerja fungsi Anda. Inisialisasi SDK klien dan koneksi database di luar fungsi handler, dan cache aset statis secara lokal di direktori. /tmp Invokasi selanjutnya yang diproses oleh instans yang sama dari fungsi Anda dapat menggunakan kembali sumber daya ini. Ini menghemat biaya dengan mengurangi waktu pengoperasian fungsi.

    Untuk menghindari potensi kebocoran data di seluruh invokasi, jangan menggunakan lingkungan eksekusi untuk menyimpan data pengguna, peristiwa, atau informasi lainnya implikasi keamanan. Jika fungsi Anda bergantung pada status yang dapat disenyapkan yang tidak dapat disimpan dalam memori di dalam handler, pertimbangkan untuk membuat fungsi terpisah atau versi terpisah dari fungsi untuk setiap pengguna.

  • Gunakan arahan keep-alive untuk mempertahankan koneksi yang persisten. Lambda membersihkan koneksi idle dari waktu ke waktu. Mencoba menggunakan ulang koneksi idle saat mengidentifikasi suatu fungsi akan menyebabkan kesalahan koneksi. Untuk mempertahankan koneksi yang persisten, gunakan arahan tetap aktif yang berkaitan dengan runtime Anda. Sebagai contoh, lihat Menggunakan Kembali Koneksi dengan Keep-Alive di Node.js.

  • Gunakan variabel lingkungan untuk meneruskan parameter operasional ke fungsi Anda. Misalnya, jika Anda ingin menulis ke bucket Amazon S3 alih-alih melakukan hard-coding nama bucket yang Anda tulis, konfigurasikan nama bucket sebagai variabel lingkungan.

  • Hindari menggunakan pemanggilan rekursif dalam fungsi Lambda Anda, di mana fungsi memanggil dirinya sendiri atau memulai proses yang dapat memanggil fungsi lagi. Hal ini dapat menyebabkan volume invokasi fungsi yang tidak diinginkan dan peningkatan biaya. Jika Anda melihat volume pemanggilan yang tidak diinginkan, setel konkurensi fungsi cadangan untuk 0 segera membatasi semua pemanggilan ke fungsi, saat Anda memperbarui kode.

  • Jangan gunakan non-dokumen, non-publik APIs dalam kode fungsi Lambda Anda. Untuk runtime AWS Lambda terkelola, Lambda secara berkala menerapkan pembaruan keamanan dan fungsional ke internal Lambda. APIs APIPembaruan internal ini mungkin tidak kompatibel ke belakang, yang menyebabkan konsekuensi yang tidak diinginkan seperti kegagalan pemanggilan jika fungsi Anda memiliki ketergantungan pada non-publik ini. APIs Lihat APIreferensi untuk daftar yang tersedia APIs untuk umum.

  • Tulis kode idempoten. Menulis kode idempoten untuk fungsi Anda memastikan bahwa peristiwa duplikat ditangani dengan cara yang sama. Kode Anda harus memvalidasi peristiwa dengan benar dan menangani peristiwa duplikat dengan anggun. Untuk informasi selengkapnya, lihat Bagaimana cara membuat fungsi Lambda saya idempoten? .