Node.js による Lambda 関数の構築 - AWS Lambda

Node.js による Lambda 関数の構築

AWS Lambda の Node.js を使用して JavaScript コードを実行できます。Lambda は Node.js のランタイムを指定して、イベントを処理するコードを実行します。コードは、管理している AWS Identity and Access Management (IAM) ロールの認証情報を使用して、AWS SDK for JavaScript を含む環境で実行されます。

Lambda は、以下の Node.js ランタイムをサポートしています。

Node.js
名前 識別子 SDK オペレーティングシステム アーキテクチャ 非推奨化 (フェーズ 1)

Node.js 18

nodejs18.x

3.188.0

Amazon Linux 2

x86_64、arm64

Node.js 16

nodejs16.x

2.1083.0

Amazon Linux 2

x86_64、arm64

Node.js 14

nodejs14.x

2.1055.0

Amazon Linux 2

x86_64、arm64

Node.js 12

nodejs12.x

2.1055.0

Amazon Linux 2

x86_64、arm64

2023 年 3 月 31 日

注記

Node 18 ランタイムは AWS SDK for JavaScript v3 を使用しています。以前のランタイムから Node 18 に関数を移行するには、GitHub の移行ワークショップの手順に従ってください。AWS SDK for JavaScript バージョン 3 の詳細については、「モジュラー AWS SDK for JavaScript が一般公開されました」のブログ記事を参照してください。

Lambda 関数は実行ロールを使用して、Amazon CloudWatch Logs にログを書き込んだり、他のサービスおよびリソースにアクセスする許可を取得したりします。関数開発用の実行ロールをお持ちでない場合は、作成してください。

実行ロールを作成するには
  1. IAM コンソールの [roles page (ロールページ)] を開きます。

  2. [ロールの作成] を選択します。

  3. 次のプロパティでロールを作成します。

    • 信頼されたエンティティLambda

    • アクセス許可AWSLambdaBasicExecutionRole

    • ロール名lambda-role

    AWSLambdaBasicExecutionRole ポリシーには、ログを CloudWatch Logs に書き込むために関数が必要とするアクセス許可があります。

後でロールにアクセス許可を追加するか、1 つの関数に固有の別のロールに差し替えることができます。

Node.js 関数を作成するには
  1. Lambda コンソールを開きます。

  2. [Create function] (関数の作成) をクリックします。

  3. 以下の設定を行います。

    • 名前my-function

    • ランタイムNode.js 18.x

    • ロール既存のロールを選択します

    • 既存のロールlambda-role

  4. [Create function] (関数の作成) をクリックします。

  5. テストイベントを設定するには、[テスト] を選択します。

  6. [イベント名] で、「test」と入力します。

  7. [Save changes] (変更の保存) をクリックします。

  8. [Test] (テスト) を選択して関数を呼び出します。

コンソールが、index.js または index.mjs という名前の単一のソースファイルを使用する Lambda 関数を作成します。このファイルを編集し、組み込みのコードエディタでファイルをさらに追加することができます。変更を保存するには [保存] を選択します。コードを実行するには、[Test] (テスト) を選択します。

注記

Lambda コンソールでは、AWS Cloud9 を使用して、ブラウザに統合開発環境を提供します。また、AWS Cloud9 を使用して、独自の環境で Lambda 関数を開発することもできます。詳細については、AWS Cloud9 ユーザーガイドの「Lambda 関数の使用」を参照してください。

index.js または index.mjs ファイルは、イベントオブジェクトとコンテキストオブジェクトを取得する handler という名前の関数をエクスポートします。これは、関数が呼び出されるときに Lambda が呼び出すハンドラー関数です。Node.js 関数のランタイムは、Lambda から呼び出しイベントを取得し、ハンドラに渡します。関数設定で、ハンドラ値は index.handler です。

関数コードを保存すると、Lambda コンソールは .zip ファイルアーカイブのデプロイパッケージを作成します。コンソール外で (SDE を使用して) 関数コードを開発するときは、デプロイパッケージを作成して、Lambda 関数にコードをアップロードします。

注記

ローカル環境でアプリケーション開発を開始するには、このガイドの GitHub リポジトリで利用可能なサンプルアプリケーションの 1 つをデプロイします。

Node.js のサンプル Lambda アプリケーション
  • blank-nodejs – ログ記録、環境変数、AWS X-Ray トレース、レイヤー、単位テスト、AWS SDK の使用を示す Node.js 関数。

  • nodejs-apig – API Gateway からのイベントを処理し、HTTP レスポンスを返す公開 API エンドポイントを持つ関数。

  • rds-mysql – RDS データベースの MySQL にクエリを中継する関数。このサンプルには、AWS Secrets Manager でパスワードが設定されたプライベート VPC とデータベースインスタンスが含まれています。

  • efs-nodejs – Amazon VPC で Amazon EFS ファイルシステムを使用する関数。このサンプルには、Lambda で使用するように設定された VPC、ファイルシステム、マウントターゲット、アクセスポイントが含まれます。

  • list-manager – 関数は Amazon Kinesis Data Streams からのイベントを処理し、Amazon DynamoDB の集計リストを更新します。この関数は、プライベート VPC の RDS データベースの MySQL に各イベントのレコードを保存します。このサンプルには、DynamoDB とデータベースインスタンスの VPC エンドポイントを持つプライベート VPC が含まれます。

  • error-processor – Node.js 関数は、指定された割合のリクエストに対してエラーを生成します。エラーが記録されると、CloudWatch Logs サブスクリプションは 2 番目の関数を呼び出します。プロセッサ関数は、AWS SDK を使用してリクエストの詳細を収集し、Amazon S3 バケットに保存します。

関数のランタイムによって、呼び出しイベントに加えて、コンテキストオブジェクトがハンドラに渡されます。コンテキストオブジェクトには、呼び出し、関数、および実行環境に関する追加情報が含まれます。詳細情報は、環境変数から入手できます。

Lambda 関数には CloudWatch Logs ロググループが付属しています。関数のランタイムは、各呼び出しに関する詳細を CloudWatch Logs に送信します。これは呼び出し時に、任意の関数が出力するログを中継します。関数がエラーを返す場合、Lambda はエラー形式を整え、それを呼び出し元に返します。

Node.js の初期化

Node.js には独特なイベントループモデルがあるため、その初期化動作が他のランタイムとは異なります。具体的に言うと、Node.js は非同期操作をサポートするノンブロッキング I/O モデルを使用します。このモデルにより、Node.js はほとんどのワークロードに対して効率的に動作できます。例えば、Node.js 関数がネットワークコールを実行する場合、そのリクエストを非同期操作として指定し、コールバックキューに置くことができます。この関数は、ネットワークコールが返されるのを待つことで、ブロックされることなくメインコールスタック内の他の操作を引き続き処理することができます。ネットワークコールが完了すると、そのコールバックが実行され、コールバックキューから削除されます。

一部の初期化タスクは非同期的に実行される場合があります。これらの非同期タスクは、呼び出し前に実行が完了することが保証されていません。例えば、AWS パラメータストアからパラメータを取得するためのネットワークコールを実行するコードは、Lambda がハンドラー関数を実行する時までに完了しない場合があります。その結果、呼び出し中は変数が null になることがあります。これを回避するには、関数のコアビジネスロジックの残りの部分を続行する前に、変数とその他の非同期コードが完全に初期化されていることを確認してください。

別の手段として、関数コードを ES モジュールとして指定することもできます。これは、関数ハンドラーの範囲外で、ファイルのトップレベルで await を使用することを可能にします。Promise ごとに await すると、ハンドラーの呼び出し前に非同期初期化コードが完了されるので、コールドスタートレイテンシーの削減におけるプロビジョニングされた同時実行の効果を最大限に引き出すことができます。詳細情報と例については、「AWS Lambda で Node.js ES モジュールと Top-Level Await を使用する」を参照してください。

ES モジュールとしての関数ハンドラーの指定

デフォルトで、Lambda は .js サフィックスが付いたファイルを CommonJS モジュールとして扱います。オプションで、コードを ES モジュールとして指定できます。これは、関数の package.json ファイルで typemodule として指定する方法と、.mjs のファイル名拡張子を使用する方法の 2 つの方法で実行できます。最初のアプローチでは、関数コードがすべての .js ファイルを ES モジュールとして扱い、2 番目のシナリオでは、.mjs で指定したファイルのみが ES モジュールになります。.mjs ファイルは常に ES モジュールであり、.cjs ファイルは常に CommonJS モジュールであることから、ES モジュールと CommonJS モジュールをそれぞれ .mjs および .cjs として命名することで、それらを混在させることができます。

Node.js 14 と Node.js 16 では、Lambda ランタイムが関数ハンドラーと同じフォルダ、またはサブフォルダから ES モジュールをロードします。Node.js 18 以降では、Lambda が ES モジュールのロード時に NODE_PATH 環境変数内のフォルダを検索します。Node.js 18 では、ES モジュールの import ステートメントを使用して、ランタイムに含まれている AWS SDK をロードできます。レイヤーから ES モジュールをロードすることも可能です。