Lambda から Lambda を呼び出す方法についてのまとめです。
環境
- macOS
- AWS Cloud9
- Node.js 8
Lambda から Lambda を呼び出す方法
他にもあるようですが、その一つとして Invoke を使います。
[Invoke] は、AWS SDK の Lambda API に含まれるメソッドです。
Invoke の基本的な使い方
基本的な使い方は次のようになります。
- ライブラリを読み込みます。
const aws = require('aws-sdk');
- Lambdaオブジェクトのインスタンスを取得します。
let lambda = new aws.Lambda({apiVersion: '2015-03-31'});
- パラメーターをJavaScriptオブジェクト形式で準備します。
const params = { Object }
- 実行します。
lambda.invoke(params, (err, data) => {})
実装
簡単な実装コードで Lambda から Lambda を呼べることを確認します。
呼び出し側
[API Gateway] から [POST]リクエストされた時に実行される Lambda関数です。
コード
const aws = require('aws-sdk');
"use strict";
let sc;
let result;
let response;
exports.handler = async (event, context, callback) => {
try {
const kintonePost = JSON.parse(event.body);
console.log(kintonePost);
sc = 200;
result = "kintone comment POST success!";
response = {
statusCode: sc,
headers: { "Content-type": "application/json" },
body: JSON.stringify( result )
};
let lambda = new aws.Lambda({apiVersion: '2015-03-31'});
const params = {
FunctionName: "<arn>", // Lambda 関数の ARN を指定
InvocationType: "RequestResponse",
Payload: JSON.stringify(event)
};
console.log(params);
lambda.invoke(params, (err, data) => {
let res = data;
if (err) {
console.log("invoke error.");
console.log(err);
context.done(err, err);
} else {
console.log("invoke success.");
console.log("response:", res);
context.done(null, res);
}
});
} catch(err) {
sc = 400;
result = err.message;
response = {
statusCode: sc,
headers: { "Content-type": "application/json" },
body: JSON.stringify( result )
};
}
callback(null, response);
};
params 説明
lambda.invoke メソッドに渡すパラメータの説明です。
- FunctionName: Lambda Function ARN を指定します。
- InvocationType: InvocationTypeを指定します。デフォルトは "RequestResponse"です。
- Payload: 呼び出すLambda関数に渡す値を指定します。JSONをそのまま渡せないので、文字列に変換して渡しています。
呼び出される側の Labmda の作成
下記の拙稿を参考にしてください。
AWS Cloud9 で AWS Lambda を開発する環境を構築してみる
呼び出される側
Lambda を作成したときの blue print [hello world] のコードを使います。
特に何もしませんが、呼び出された時にログを出力して、コールバックに呼び出し元から渡された内容を戻します。
成功すれば、CloudWatchログで出力が確認できるはずです。
コード
"use strict";
console.log('Loading function');
exports.handler = async (event, context, callback) => {
console.log('Received event:', JSON.stringify(event, null, 2));
console.log('event.body:', JSON.parse(event.body));
// console.log('value1 =', event.key1);
// console.log('value2 =', event.key2);
// console.log('value3 =', event.key3);
// return event.key1; // Echo back the first key value
// throw new Error('Something went wrong');
callback(null, JSON.parse(event.body));
};
呼び出される側の Labmda の作成
Lambdaアプリの上で右クリックして [Create Here] を選択。
[Function name] を入力します。
[blue print] は node.js [hello-world] を選択します。
blue print の [hello-world] です。
実行結果
Cloud9(ローカル開発環境) から リモート環境へデプロイして実行します。
Cloud9からリモートの API Gateway 経由で Lambdaを実行する
Cloud9 から リモートのAPI Gateway を実行
テスト用のJSONを渡します。
{
"param1": "value1"
}
ログの確認
CloudWatchログを確認します。
呼び出し側のログ
呼び出された側からステータスコードと値が戻ってきています。
response: { StatusCode: 200,
Payload: '{"param1":"value1"}' }
呼び出された側のログ
呼び出し側から渡されたパラメーターが取得できています。
event.body: { param1: 'value1' }
アプリから API Gateway 経由で Lambda を実行する
kintoneの Webhook を使い、下記の流れで確認します。
- kintoneアプリにレコード追加
- kintoneアプリの アプリの設定→Webhook→Webhookログ を確認
- cybozu.com共通管理 の システム管理→監査ログ を確認
- AWS の CloudWatchログを確認
Webhookの設定は下記になっています。
URLに AWS API Gateway の API エンドポイント を設定しています。
呼び出し側の AWS CloudWatchログです。
kintoneのレコード情報が渡ってきています。
呼び出される側の AWS CloudWatchログです。
kintoneレコードをJSONに変換して表示されています。
外部から AWS API Gateway 経由で Lambdaを呼び出して、さらに別の Lambda を呼び出すことができました。
関連リンク
AWS関連
- Node.js 8.10 runtime now available in AWS Lambda
- AWS LambdaからLambdaを呼ぶ
- Connpass APIをLambdaから扱う〜Lambdaの非同期呼び出しによる分散処理〜
- AWS Lambda invoke
- Node.js での AWS Lambda Context オブジェクト
- Node.js の AWS Lambda 関数ハンドラー
- チュートリアル: Lambda 関数の作成と使用
- AWS SDK を使用して Lambda 関数を呼び出す際の再試行とタイムアウトの問題をトラブルシューティングする方法について教えてください。
- AWS SDK for JavaScript のドキュメント
- AWS SDK for JavaScript