Node.js の AWS Lambda 関数ハンドラー - AWS Lambda

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

Node.js の AWS Lambda 関数ハンドラー

Lambda 関数ハンドラーは、イベントを処理する関数コード内のメソッドです。関数が呼び出されると、Lambda はハンドラーメソッドを実行します。関数は、ハンドラーが応答を返すか、終了するか、タイムアウトするまで実行されます。

次のサンプル関数は、イベントオブジェクトの内容をログに記録し、ログの場所を返します。

注記

このページは、CommonJS と ES モジュールハンドラーの両方の例を示します。これらの 2 つのハンドラータイプの違いについては、「ES モジュールとしての関数ハンドラーの指定」を参照してください。

CommonJS module handler
exports.handler = async function (event, context) { console.log("EVENT: \n" + JSON.stringify(event, null, 2)); return context.logStreamName; };
ES module handler
export const handler = async (event, context) => { console.log("EVENT: \n" + JSON.stringify(event, null, 2)); return context.logStreamName; };

関数を設定すると、ハンドラー設定の値はファイル名とエクスポートしたハンドラーメソッドの名前をドットで区切ったものになります。コンソールのデフォルトと、このガイドの例では、index.handler です。これは、 handler ファイルからエクスポートされた index.js メソッドを示します。

ランタイムでは、ハンドラーメソッドに引数を渡します。最初の引数は、呼び出し元からの情報を含む event オブジェクトです。呼び出し元は、Invoke を呼び出してこの情報を JSON 形式の文字列として渡し、ランタイムはそれをオブジェクトに変換します。AWS のサービスで関数を呼び出す場合、そのイベント構造はサービスによって異なります

2 番目の引数は、コンテキストオブジェクトです。この引数には、呼び出し、関数、および実行環境に関する情報が含まれます。前述の例では、関数は、コンテキストオブジェクトからログストリームの名前を取得し、それを呼び出し元に返します。

コールバック引数を使用することもできます。これは、非同期ではないハンドラーで呼び出してレスポンスを送信できる関数です。コールバックの代わりに async/await を使用することをお勧めします。async/await により、読みやすさ、エラー処理、および効率が向上します。async/await とコールバックの違いの詳細については、「コールバックの使用」を参照してください。

async/await の使用

コードが非同期タスクを実行する場合は、async/await パターンを使用して、ハンドラーが実行を確実に終了するようにします。async/await は、Node.js で非同期コードを記述するための簡潔で読みやすい方法であり、ネストされたコールバックや連鎖する promise を必要としません。async/await を使用すると、非同期かつノンブロッキングでありながら、同期コードのように読み取るコードを記述できます。

async キーワードは関数を非同期としてマークし、await キーワードは Promise が解決されるまで関数の実行を一時停止します。

注記

非同期イベントが完了するまでお待ちください。非同期イベントが完了する前に関数が戻る場合、関数が失敗したり、アプリケーションで予期しない動作が発生したりする可能性があります。これは、forEach ループに非同期イベントが含まれている場合に発生します。forEach ループは同期呼び出しを想定しています。詳細については、Mozilla ドキュメントの「Array.prototype.forEach()」を参照してください。

CommonJS module handler
例 – async/await を使用した HTTP リクエスト
const https = require("https"); let url = "https://aws.amazon.com/"; exports.handler = async function (event) { let statusCode; await new Promise(function (resolve, reject) { https.get(url, (res) => { statusCode = res.statusCode; resolve(statusCode); }).on("error", (e) => { reject(Error(e)); }); }); console.log(statusCode); return statusCode; };
ES module handler
例 – async/await を使用した HTTP リクエスト

この例では、nodejs18.x ランタイムで使用できる fetch を使用します。

const url = "https://aws.amazon.com/"; export const handler = async(event) => { try { // fetch is available with Node.js 18 const res = await fetch(url); console.info("status", res.status); return res.status; } catch (e) { console.error(e); return 500; } };

次の例では、async/await を使用して Amazon Simple Storage Service バケットを一覧表示します。

注記

この例を使用する前に、関数の実行ロールに Amazon S3 の読み取り許可があることを確認してください。

CommonJS module handler
例 – async/await を使用した AWS SDK v2

この例では、nodejs16.x Lambda ランタイムに含まれている AWS SDK for JavaScript v2 を使用します。

const AWS = require('aws-sdk') const s3 = new AWS.S3() exports.handler = async function(event) { const buckets = await s3.listBuckets().promise() return buckets }
ES module handler
例 – async/await を使用した AWS SDK v3

この例では、nodejs18.x ランタイムで使用可能な AWS SDK for JavaScript v3 を使用します。

import {S3Client, ListBucketsCommand} from '@aws-sdk/client-s3'; const s3 = new S3Client({region: 'us-east-1'}); export const handler = async(event) => { const data = await s3.send(new ListBucketsCommand({})); return data.Buckets; };

コールバックの使用

コールバックを使用する代わりに、async/await を使用して関数ハンドラーを宣言することをお勧めします。いくつかの理由により、async/await の方が適しています。

  • 読みやすさ: async/await コードは、コールバックコードよりも読みやすく理解しやすいです。コールバックコードは、すぐに理解するのが難しくなり、コールバック地獄に陥る可能性があります。

  • デバッグとエラー処理: コールバックベースのコードのデバッグは難しい場合があります。コールスタックを追跡するのが難しくなり、エラーが簡単に隠れてしまう可能性があります。async/await では、try/catch ブロックを使用してエラーを処理できます。

  • 効率: コールバックでは、多くの場合、コードのさまざまな部分を切り替える必要があります。async/await を使用すると、コンテキストスイッチの回数を減らすことができるため、コードがより効率的になります。

ハンドラーでコールバックを使用すると、関数は、イベントループが空になるか、関数がタイムアウトするまで実行を続けます。レスポンスは、すべてのイベントループタスクが完了するまで、呼び出し元に送信されません。関数がタイムアウトした場合は、エラーが返ります。context を callbackWaitsForEmptyEventLoop false に設定することで、レスポンスをすぐに送信するようにランタイムを設定できます。

コールバック関数は、Error とレスポンスの 2 つの引数を取ります。応答オブジェクトは、JSON.stringify と互換性がある必要があります。

次の例の関数では、URL をチェックし、ステータスコードを呼び出し元に返します。

CommonJS module handler
例 – callback を使用した HTTP リクエスト
const https = require("https"); let url = "https://aws.amazon.com/"; exports.handler = function (event, context, callback) { https.get(url, (res) => { callback(null, res.statusCode); }).on("error", (e) => { callback(Error(e)); }); };
ES module handler
例 – callback を使用した HTTP リクエスト
import https from "https"; let url = "https://aws.amazon.com/"; export function handler(event, context, callback) { https.get(url, (res) => { callback(null, res.statusCode); }).on("error", (e) => { callback(Error(e)); }); }

次の例では、Amazon S3 のレスポンスは、有効になるとすぐに呼び出し元に返ります。イベントループで実行されているタイムアウトは停止し、次に関数が呼び出されたときに実行を継続します。

注記

この例を使用する前に、関数の実行ロールに Amazon S3 の読み取り許可があることを確認してください。

CommonJS module handler
例 – を使用した AWS SDK v2 callbackWaitsForEmptyEventLoop

この例では、nodejs16.x Lambda ランタイムに含まれている AWS SDK for JavaScript v2 を使用します。

const AWS = require("aws-sdk"); const s3 = new AWS.S3(); exports.handler = function (event, context, callback) { context.callbackWaitsForEmptyEventLoop = false; s3.listBuckets(null, callback); setTimeout(function () { console.log("Timeout complete."); }, 5000); };
ES module handler
例 – を使用した AWS SDK v3 callbackWaitsForEmptyEventLoop

この例では、nodejs18.x ランタイムで使用可能な AWS SDK for JavaScript v3 を使用します。

import AWS from "@aws-sdk/client-s3"; const s3 = new AWS.S3({}); export const handler = function (event, context, callback) { context.callbackWaitsForEmptyEventLoop = false; s3.listBuckets({}, callback); setTimeout(function () { console.log("Timeout complete."); }, 5000); };