AWSのLambda (Node.js) から他のLambdaを呼び出す

2021-06-18

Invokeで同期・非同期で他のLambda関数を呼び出す

『Invoke』を使ってLambda関数を呼び出せます。
関数を同期的に呼び出す(応答を待つ)ことも、非同期的に呼び出す(応答を待たない)こともできます。
同期の場合はInvocationTypeをRequestResponse、非同期の場合はInvocationTypeをEventに設定します。

  1. 同期呼び出し(RequestResponse)
  2. 非同期呼び出し(Event)
  3. 非同期呼び出しのパラメータ容量制限
  4. 参考

1. 同期呼び出し(RequestResponse)

同期呼び出しで関数の応答を待つことで、呼び出し先のLambda関数の結果を使った処理を続けられます。
InvocationTypeの部分にRequestResponseを指定すると同期呼び出しを行えます。

コード(呼び出し先Lambda関数)

exports.handler = async (event) => {
    let res=event;
    res["add"]=event.a+event.b;
    return res;
};

コード(呼び出し元Lambda関数)

var aws = require('aws-sdk');
var lambda = new aws.Lambda();

exports.handler = async (event) => {
    
    let invoke_prm={
        function_name:"yobidashisaki",
        body:{a:12,b:23},
    };
    let invoke_res=await lambda_invoke(invoke_prm);
    
    return invoke_res;
};

function lambda_invoke(obj){
    return new Promise((resolve, reject) => {
        let params = {
            FunctionName: obj.function_name,//呼び出し先関数名
            InvocationType: "RequestResponse",//同期
            //InvocationType: "Event",//非同期
            Payload: JSON.stringify(obj.body),//パラメータ
        };
        lambda.invoke(params, function(err, data){
            if(err) {
                reject(err, err);
            } else {
                resolve(data);
            }
        });
    });
}

結果

{
  "StatusCode": 200,
  "ExecutedVersion": "$LATEST",
  "Payload": "{\"a\":12,\"b\":23,\"add\":35}"
}

呼び出し先関数の結果はPayloadに入り、文字列で返ってきます。

2. 非同期呼び出し(Event)

非同期呼び出しにより関数の応答を待たず、処理を続けられます。
そのため呼び出し先関数の結果を利用した処理は行えません。
呼び出し先関数の結果を利用しない場合、呼び出し先関数の処理が重い・時間がかかる場合などに利用します。
InvocationTypeの部分にEventを指定すると非同期呼び出しを行えます。

コード

var aws = require('aws-sdk');
var lambda = new aws.Lambda();

exports.handler = async (event) => {
    
    let invoke_prm={
        function_name:"yobidashisaki",
        body:{a:12,b:23},
    };
    let invoke_res=await lambda_invoke(invoke_prm);
    
    return invoke_res;
};

function lambda_invoke(obj){
    return new Promise((resolve, reject) => {
        let params = {
            FunctionName: obj.function_name,//呼び出し先関数名
            //InvocationType: "RequestResponse",//同期
            InvocationType: "Event",//非同期
            Payload: JSON.stringify(obj.body),//パラメータ
        };
        lambda.invoke(params, function(err, data){
            if(err) {
                reject(err, err);
            } else {
                resolve(data);
            }
        });
    });
}

結果

{
  "StatusCode": 202,
  "Payload": ""
}

同期と違ってStatusCodeが202となり、Payloadに結果は返ってきません。

3. 非同期呼び出しのパラメータ容量制限

非同期でパラメータを送信する場合、262144byteという容量制限があるようです。
パラメータが大きい場合は、分割送信するなどの対策が必要でした。

エラー内容

{
  "errorType": "RequestEntityTooLargeException",
  "errorMessage": "2177786 byte payload is too large for the Event invocation type (limit 262144 bytes)",
}

参考