View a markdown version of this page

Tentukan pengendali fungsi Lambda di TypeScript - AWS Lambda

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

Tentukan pengendali fungsi Lambda di TypeScript

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 batas waktu.

Halaman ini menjelaskan cara bekerja dengan penangan fungsi Lambda di TypeScript, termasuk opsi untuk penyiapan proyek, konvensi penamaan, dan praktik terbaik. Halaman ini juga menyertakan contoh fungsi TypeScript Lambda yang mengambil informasi tentang pesanan, menghasilkan tanda terima file teks, dan menempatkan file ini dalam bucket Amazon Simple Storage Service (Amazon S3). Untuk informasi tentang cara menerapkan fungsi Anda setelah menulisnya, lihat Terapkan TypeScript kode transpiled di Lambda dengan arsip file.zip atauTerapkan TypeScript kode yang ditranspilasikan di Lambda dengan gambar kontainer.

Menyiapkan TypeScript proyek Anda

Gunakan lingkungan pengembangan terintegrasi lokal (IDE) atau editor teks untuk menulis kode TypeScript fungsi Anda. Anda tidak dapat membuat TypeScript kode di konsol Lambda.

Ada beberapa cara untuk menginisialisasi proyek TypeScript Lambda. Misalnya, Anda dapat membuat proyek menggunakannpm, membuat AWS SAM aplikasi, atau membuat AWS CDK aplikasi. Untuk membuat proyek menggunakannpm:

npm init

Kode fungsi Anda berada dalam .ts file, yang Anda transpilasi ke JavaScript file pada waktu pembuatan. Anda dapat menggunakan esbuild atau TypeScript kompiler Microsoft (tsc) untuk mentranspilasi kode Anda ke. TypeScript JavaScript Untuk menggunakan esbuild, tambahkan sebagai ketergantungan pengembangan:

npm install -D esbuild

Proyek fungsi TypeScript Lambda yang khas mengikuti struktur umum ini:

/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

Contoh kode fungsi TypeScript Lambda

Contoh kode fungsi Lambda berikut mengambil informasi tentang pesanan, menghasilkan tanda terima file teks, dan menempatkan file ini dalam bucket Amazon S3. Contoh ini mendefinisikan jenis peristiwa khusus (OrderEvent). Untuk mempelajari cara mengimpor definisi tipe untuk sumber AWS peristiwa, lihat Definisi tipe untuk Lambda.

catatan

Contoh ini menggunakan pengendali modul ES. Lambda mendukung modul ES dan penangan CommonJS. Untuk informasi selengkapnya, lihat Modul CommonJS dan ES.

contoh fungsi index.ts 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'}`); } }

index.tsFile ini berisi bagian kode berikut:

  • importblok: Gunakan blok ini untuk menyertakan pustaka yang dibutuhkan fungsi Lambda Anda, seperti klien AWS SDK.

  • const s3Clientdeklarasi: Ini menginisialisasi klien Amazon S3 di luar fungsi handler. Hal ini menyebabkan Lambda menjalankan kode ini selama fase in isialisasi, dan klien dipertahankan untuk digunakan kembali di beberapa pemanggilan.

  • type OrderEvent: Mendefinisikan struktur peristiwa input yang diharapkan.

  • export const handler: Ini adalah fungsi handler utama yang dipanggil Lambda. Saat menerapkan fungsi Anda, tentukan index.handler untuk properti Handler. Nilai Handler properti adalah nama file dan nama metode handler yang diekspor, dipisahkan oleh titik.

  • uploadReceiptToS3function: Ini adalah fungsi pembantu yang direferensikan oleh fungsi handler utama.

Agar fungsi ini berfungsi dengan baik, peran pelaksanaannya harus memungkinkan s3:PutObject tindakan. Juga, pastikan Anda mendefinisikan variabel RECEIPT_BUCKET lingkungan. Setelah pemanggilan berhasil, bucket Amazon S3 harus berisi file tanda terima.

Modul CommonJS dan ES

Node.js mendukung dua sistem modul: modul CommonJS dan ECMAScript (modul ES). Lambda merekomendasikan penggunaan modul ES karena mendukung menunggu tingkat atas, yang memungkinkan tugas asinkron diselesaikan selama inisialisasi lingkungan eksekusi.

Node.js memperlakukan file dengan ekstensi nama .cjs file sebagai modul CommonJS sementara .mjs ekstensi menunjukkan modul ES. Secara default, Node.js memperlakukan file dengan ekstensi nama .js file sebagai modul CommonJS. Anda dapat Node.js mengonfigurasi untuk memperlakukan .js file sebagai modul ES dengan menentukan seperti module dalam package.json file fungsi. type Anda dapat mengonfigurasi Node.js di Lambda untuk mendeteksi secara otomatis apakah .js file harus diperlakukan sebagai CommonJS atau sebagai modul ES dengan menambahkan —experimental-detect-module flag ke variabel NODE_OPTIONS lingkungan. Untuk informasi selengkapnya, lihat Node.js Fitur eksperimental.

Contoh berikut menunjukkan penangan fungsi yang ditulis menggunakan modul ES dan modul CommonJS. Contoh yang tersisa di halaman ini semua menggunakan modul ES.

Node.js inisialisasi

Node.js menggunakan I/O model non-pemblokiran yang mendukung operasi asinkron yang efisien menggunakan loop peristiwa. Misalnya, jika Node.js membuat panggilan jaringan, fungsi terus memproses operasi lain tanpa memblokir respons jaringan. Ketika respons jaringan diterima, itu ditempatkan ke dalam antrian panggilan balik. Tugas dari antrian diproses saat tugas saat ini selesai.

Lambda merekomendasikan penggunaan menunggu tingkat atas sehingga tugas asinkron yang dimulai selama inisialisasi lingkungan eksekusi selesai selama inisialisasi. Tugas asinkron yang tidak selesai selama inisialisasi biasanya dijalankan selama pemanggilan fungsi pertama. Hal ini dapat menyebabkan perilaku atau kesalahan yang tidak terduga.

Misalnya, inisialisasi fungsi Anda mungkin membuat panggilan jaringan untuk mengambil parameter dari AWS Parameter Store. Jika tugas ini tidak selesai selama inisialisasi, nilainya mungkin nol selama pemanggilan. Mungkin juga ada penundaan antara inisialisasi dan pemanggilan yang dapat memicu kesalahan dalam operasi yang sensitif terhadap waktu. Secara khusus, panggilan AWS layanan dapat bergantung pada tanda tangan permintaan yang sensitif terhadap waktu, yang mengakibatkan kegagalan panggilan layanan jika panggilan tidak selesai selama fase inisialisasi.

Menyelesaikan tugas selama inisialisasi biasanya meningkatkan kinerja cold start, dan pertama kali memanggil kinerja saat menggunakan Provisioned Concurrency. Untuk informasi lebih lanjut, lihat posting blog kami Menggunakan modul Node.js ES dan menunggu tingkat atas. AWS Lambda

Konvensi penamaan handler

Saat Anda mengonfigurasi fungsi, nilai pengaturan Handler adalah nama file dan nama metode handler yang diekspor, dipisahkan oleh titik. Default untuk fungsi yang dibuat di konsol dan untuk contoh dalam panduan ini adalahindex.handler. Ini menunjukkan handler metode yang diekspor dari index.mjs file index.js atau.

Jika Anda membuat fungsi di konsol menggunakan nama file atau nama pengendali fungsi yang berbeda, Anda harus mengedit nama handler default.

Untuk mengubah nama pengendali fungsi (konsol)
  1. Buka halaman Fungsi di konsol Lambda dan pilih fungsi Anda.

  2. Pilih tab Kode.

  3. Gulir ke bawah ke panel pengaturan Runtime dan pilih Edit.

  4. Di Handler, masukkan nama baru untuk pengendali fungsi Anda.

  5. Pilih Simpan.

Mendefinisikan dan mengakses objek peristiwa input

JSON adalah format input yang paling umum dan standar untuk fungsi Lambda. Dalam contoh ini, fungsi mengharapkan input yang mirip dengan berikut ini:

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

Saat bekerja dengan fungsi Lambda di TypeScript, Anda dapat menentukan bentuk peristiwa input menggunakan tipe atau antarmuka. Dalam contoh ini, kita mendefinisikan struktur acara menggunakan tipe:

type OrderEvent = { order_id: string; amount: number; item: string; }

Setelah Anda menentukan jenis atau antarmuka, gunakan di tanda tangan handler Anda untuk memastikan keamanan tipe:

export const handler = async (event: OrderEvent): Promise<string> => {

Selama kompilasi, TypeScript memvalidasi bahwa objek acara berisi bidang yang diperlukan dengan tipe yang benar. Misalnya, TypeScript kompiler melaporkan kesalahan jika Anda mencoba menggunakan event.order_id sebagai angka atau event.amount sebagai string.

Pola handler yang valid untuk TypeScript fungsi

Sebaiknya gunakan untuk mendeklar async/await asikan pengendali fungsi alih-alih menggunakan callback. Async/await adalah cara ringkas dan mudah dibaca untuk menulis kode asinkron, tanpa perlu panggilan balik bersarang atau janji rantai. Dengan async/await, Anda dapat menulis kode yang dibaca seperti kode sinkron, sementara masih asinkron dan non-pemblokiran.

Contoh di bagian ini menggunakan S3Event tipe. Namun, Anda dapat menggunakan jenis AWS acara lainnya dalam paket @ types/aws -lambda, atau menentukan jenis acara Anda sendiri. Untuk menggunakan jenis dari@types/aws-lambda:

  1. Tambahkan @types/aws-lambda paket sebagai ketergantungan pengembangan:

    npm install -D @types/aws-lambda
  2. Impor jenis yang Anda butuhkan, sepertiContext,S3Event, atauCallback.

penangan fungsi asinkron (disarankan)

asyncKata kunci menandai fungsi sebagai asinkron, dan await kata kunci menjeda eksekusi fungsi sampai a Promise diselesaikan. Handler menerima argumen berikut:

Berikut adalah tanda tangan yang valid untuk async/await pola:

export const handler = async (event: S3Event): Promise<void> => { };
export const handler = async (event: S3Event, context: Context): Promise<void> => { };
catatan

Saat memproses array item secara asinkron, pastikan untuk menggunakan wait with Promise.all untuk memastikan semua operasi selesai. Metode seperti forEach jangan menunggu panggilan balik async selesai. Untuk informasi selengkapnya, lihat Array.prototype.forEach () dalam dokumentasi Mozilla.

Penangan fungsi sinkron

Jika fungsi Anda tidak melakukan tugas asinkron apa pun, Anda dapat menggunakan pengendali fungsi sinkron, menggunakan salah satu tanda tangan fungsi berikut:

export const handler = (event: S3Event): void => { };
export const handler = (event: S3Event, context: Context): void => { };

Penangan fungsi streaming respons

Lambda mendukung streaming respons dengan Node.js. Penangan fungsi streaming respons menggunakan dekorator awsLambda.streamifyResponse () dan mengambil 3 parameter: event, responseStream, dan context. Tanda tangan fungsi adalah:

export const handler = awslambda.streamifyResponse(async (event: APIGatewayProxyEvent, responseStream: NodeJS.WritableStream, context: Context) => { });

Untuk informasi selengkapnya, lihat Streaming respons untuk fungsi Lambda.

Callback-based penangan fungsi

catatan

Callback-based function handler hanya didukung hingga Node.js 22. Mulai dari Node.js 24, tugas asinkron harus diimplementasikan menggunakan penangan fungsi async.

Callback-based function handler dapat menggunakan argumen event, context, dan callback. Argumen callback mengharapkan respon Error dan respon, yang harus JSON-serializable ada.

Berikut adalah tanda tangan yang valid untuk pola pengendali panggilan balik:

export const handler = (event: S3Event, context: Context, callback: Callback<void>): void => { };

Fungsi terus dijalankan sampai event loop kosong atau fungsi habis waktu. Respons tidak dikirimkan ke invoker hingga semua tugas loop peristiwa selesai. Jika waktu fungsi habis, kesalahan akan dikembalikan. Anda dapat mengonfigurasi runtime untuk mengirim respons segera dengan menyetel context.call WaitsForEmptyEventLoop back ke false.

contoh TypeScript fungsi dengan callback

Contoh berikut menggunakanAPIGatewayProxyCallback, yang merupakan jenis callback khusus khusus untuk integrasi API Gateway. Sebagian besar sumber AWS peristiwa menggunakan Callback tipe generik yang ditunjukkan pada tanda tangan di atas.

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

Menggunakan SDK untuk JavaScript v3 di handler Anda

Seringkali, Anda akan menggunakan fungsi Lambda untuk berinteraksi dengan atau membuat pembaruan ke AWS sumber daya lain. Cara paling sederhana untuk berinteraksi dengan sumber daya ini adalah dengan menggunakan AWS SDK untuk JavaScript. Semua runtime Lambda Node.js yang didukung termasuk SDK untuk JavaScript versi 3. Namun, kami sangat menyarankan Anda menyertakan klien AWS SDK yang Anda butuhkan dalam paket penerapan Anda. Ini memaksimalkan kompatibilitas mundur selama pembaruan runtime Lambda di masa mendatang.

Untuk menambahkan dependensi SDK ke fungsi Anda, gunakan npm install perintah untuk klien SDK tertentu yang Anda butuhkan. Dalam kode contoh, kami menggunakan klien Amazon S3. Tambahkan dependensi ini dengan menjalankan perintah berikut di direktori yang berisi package.json file Anda:

npm install @aws-sdk/client-s3

Dalam kode fungsi, impor klien dan perintah yang Anda butuhkan, seperti contoh fungsi menunjukkan:

import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';

Kemudian, inisialisasi klien Amazon S3:

const s3Client = new S3Client();

Dalam contoh ini, kami menginisialisasi klien Amazon S3 kami di luar fungsi handler utama untuk menghindari keharusan menginisialisasi setiap kali kami memanggil fungsi kami. Setelah menginisialisasi klien SDK, Anda kemudian dapat menggunakannya untuk membuat panggilan API untuk AWS layanan tersebut. Kode contoh memanggil tindakan Amazon S3 PutObject API sebagai berikut:

const command = new PutObjectCommand({ Bucket: bucketName, Key: key, Body: receiptContent });

Mengakses variabel lingkungan

Dalam kode handler Anda, Anda dapat mereferensikan variabel lingkungan apa pun dengan menggunakanprocess.env. Dalam contoh ini, kita mereferensi RECEIPT_BUCKET kan variabel lingkungan yang ditentukan menggunakan baris kode berikut:

// Access environment variables const bucketName = process.env.RECEIPT_BUCKET; if (!bucketName) { throw new Error('RECEIPT_BUCKET environment variable is not set'); }

Menggunakan status global

Lambda menjalankan kode statis Anda selama fase inisialisasi sebelum memanggil fungsi Anda untuk pertama kalinya. Sumber daya yang dibuat selama inisialisasi tetap berada di memori di antara pemanggilan, sehingga Anda dapat menghindari keharusan membuatnya setiap kali Anda memanggil fungsi Anda.

Dalam kode contoh, kode inisialisasi klien S3 berada di luar handler. Runtime menginisialisasi klien sebelum fungsi menangani peristiwa pertamanya, dan klien tetap tersedia untuk digunakan kembali di semua pemanggilan.

Praktik terbaik kode untuk fungsi TypeScript Lambda

Ikuti panduan ini saat membangun fungsi Lambda:

  • 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 runtime Node.js dan Python, ini termasuk AWS SDK. 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. Ini akan mengurangi jumlah waktu yang dibutuhkan untuk mengunduh dan membongkar paket deployment Anda sebelum invokasi.

Manfaatkan penggunaan kembali lingkungan eksekusi untuk meningkatkan kinerja fungsi Anda. Inisialisasi klien SDK dan koneksi basis data di luar fungsi handler, dan lakukan caching 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 direktif 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 Kem bali Koneksi dengan Keep-Alive in 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 fungsi reservasi konkurensi ke 0 segera untuk membatasi semua pemanggilan ke fungsi, saat Anda memperbarui kode.

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

Tulis kode idempotent. Menulis kode idempotent 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 lebih lanjut, lihat Bagaimana cara membuat fungsi Lambda saya idempoten? .