【入門】LambdaとAPI Gatewayの使い方

「APIリクエストを通じてLambda関数を呼び出し、レスポンスを返す」という簡単な例を通じて LambdaAPI Gateway の使い方を確認します。

作るもの

Lambda はイベントに応じて、コードを実行できるサービスです。

今回は、API Gateway で作成したAPIリクエストをトリガーに Lambda関数 を実行させます。最終的な動作イメージを示します。

519-aws-lambda-introduction_image.png
  • /message?name=wakuwaku というパスでリクエストを飛ばしたら、指定された Lambda関数 が実行されます。
  • Lambda関数nameパラメーター の内容を読み取り Hello wakuwaku という文字列をレスポンスとして返します。
  • Lambda関数 の実行ログは CloudWatch に保存されます。

Lambda関数作成

関数とロールの作成

519-aws-lambda-introduction_1_1.png

Lambdaの管理画面を開き、関数の作成をクリックします。

519-aws-lambda-introduction_1_2.png

ランタイムとしてPython Java Goなどを利用できます。ここでは、Node.js 8.10 を利用します。

今回、Lambda関数を初めて作成するのですが、Lambda関数用のロールも作成しておきます。
カスタムロールの作成をクリックします。

519-aws-lambda-introduction_1_3.png

カスタムロールの作成をクリックしたので、IAMのページが開きました。そのまま許可をクリックします。

Lambda関数の実行ログを保存するために、CloudWatch Logsへの書き込み権限を付与されています。

519-aws-lambda-introduction_1_4.png

IAMページが閉じ、Lambda関数の作成ページに作成したロールが設定されました。関数の作成をクリックします。

関数が生成されました。

519-aws-lambda-introduction_1_5.png

上記画面で以下のような設定をすることができます。

  • トリガーの追加
  • 関数コードの編集
  • メモリーの設定
  • タイムアウトの設定
  • 同時実行数の設定

トリガーの設定

今回は、APIリクエストをトリガーにLambda関数を実行させます。

トリガーの設定は、後述する API Gateway の設定時に行います。

補足:代表的なユースケース

関数コードの編集

以下のコードを貼り付けます。

exports.handler = async (event) => {
    console.log(event)
    console.log(process.env)

    const response = {
        statusCode: 200,
        body: 'Hello',
    }
    return response
}
519-aws-lambda-introduction_1_6.png

環境変数の設定

環境変数を設定できます。ここでは動作確認用として以下のように設定しました。

519-aws-lambda-introduction_1_7.png

動作確認

519-aws-lambda-introduction_1_8.png

保存がクリック済みか確認します。

テストイベントの設定をクリックします。

519-aws-lambda-introduction_1_9.png

関数実行時に渡されるeventを設定します。

519-aws-lambda-introduction_1_10.png

イベントが設定されました。テストをクリックすると関数が実行されます。

以下、実行結果です。

519-aws-lambda-introduction_1_11.png
  • return response で返した内容が表示されています。
  • console.log(event) の出力結果です。作成した テストイベント の内容が表示されています。
  • console.log(process.env) の出力結果です。設定した環境変数の内容が表示されています。

API作成

APIの作成

519-aws-lambda-introduction_2_1.png

API Gatewayの管理画面を開き、今すぐ始めるをクリックします。

519-aws-lambda-introduction_2_2.png

新しいAPIを選択します。API名を入力してAPIの作成をクリックします。

リソースの作成

519-aws-lambda-introduction_2_3.png

リソースの作成をクリックします。

519-aws-lambda-introduction_2_4.png

今回は、messageというリソースを作成します。

メソッドの作成とLambda関数紐付け

519-aws-lambda-introduction_2_5.png

メソッドの作成をクリックします。

519-aws-lambda-introduction_2_6.png

GETメソッドを選択します。

519-aws-lambda-introduction_2_7.png

先ほど作成したLambda関数を選択します。

デプロイ

519-aws-lambda-introduction_2_8.png

APIのデプロイをクリックします。

519-aws-lambda-introduction_2_9.png

ステージ名を選択できます。開発環境、ステージ環境、本番環境といった使い分けができます。

今回はdevというステージにします。

519-aws-lambda-introduction_2_10.png

APIのエンドポイントが表示されます。動作確認でこのURLを利用します。

動作確認

curlで動作確認します。先ほどのURLに message を追加して呼び出します。

$ curl https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/message
{"statusCode":200,"body":"Hello"}

Lambda関数の出力結果がレスポンスとして確認できました。

519-aws-lambda-introduction_2_11.png

CloudWatchのログでLambda関数の実行ログを確認できます。

APIのパラメーターをLambda関数に渡す

console.log(event) の出力結果
( Before )

console.log(event) の出力結果はCloudWatchのログで確認したところ以下のようになっていました。

2019-01-02T09:58:00.598Z e3639496-0e74-11e9-87d6-ed0437c0370d
{}

event 経由でリクエストパラメーターを渡せるように調整します。

Lambdaプロキシ統合の使用

519-aws-lambda-introduction_3_1.png

Lambdaプロキシ統合の使用にチェックを入れると、event 経由でリクエストパラメーターを渡せるようになります。

設定を変更したので、再度APIをデプロイします。

参考

console.log(event) の出力結果
( After )

Lambdaプロキシ統合の使用 にチェックを入れたことによって、console.log(event) の出力結果がどのように変わるのか確認します。

nameパラメーターを付与してAPIを呼び出します。

$ curl https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/message?name=wakuwaku
Hello 

レスポンスとして、 Hello のみが返るようになりました。

console.log(event) の出力は以下のようになりました。

2019-01-02T10:17:03.844Z 8cd4bd30-0e77-11e9-b798-19091d0a23a5 { resource: '/message',
path: '/message',
httpMethod: 'GET',
headers:
{ accept: '*/*',
Host: 'xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com',
'User-Agent': 'curl/7.54.0',
'X-Amzn-Trace-Id': 'Root=XXXXXXXXXXXXXXXXXXXXXXXXXX',
'X-Forwarded-For': 'xxx.xxx.xxx.xxx',
'X-Forwarded-Port': '443',
'X-Forwarded-Proto': 'https' },
multiValueHeaders:
{ accept: [ '*/*' ],
Host: [ 'xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com' ],
'User-Agent': [ 'curl/7.54.0' ],
'X-Amzn-Trace-Id': [ 'Root=XXXXXXXXXXXXXXXXXXXXXXXXXX' ],
'X-Forwarded-For': [ 'xxx.xxx.xxx.xxx' ],
'X-Forwarded-Port': [ '443' ],
'X-Forwarded-Proto': [ 'https' ] },
queryStringParameters: { name: 'wakuwaku' },
multiValueQueryStringParameters: { name: [ 'wakuwaku' ] },
pathParameters: null,
stageVariables: null,
requestContext:
{ resourceId: 'xxxxxx',
resourcePath: '/message',
httpMethod: 'GET',
extendedRequestId: 'S3tg-XXXXXXXXXXX',
requestTime: '02/Jan/2019:10:17:03 +0000',
path: '/dev/message',
accountId: 'XXXXXXXXXXXXX',
protocol: 'HTTP/1.1',
stage: 'dev',
domainPrefix: 'xxxxxxxx',
requestTimeEpoch: XXXXXXXXXXXX,
requestId: 'XXXXXXXXXXXXXXXXXXXXXXX',
identity:
{ cognitoIdentityPoolId: null,
accountId: null,
cognitoIdentityId: null,
caller: null,
sourceIp: 'xxx.xxx.xxx.xxx',
accessKey: null,
cognitoAuthenticationType: null,
cognitoAuthenticationProvider: null,
userArn: null,
userAgent: 'curl/7.54.0',
user: null },
domainName: 'xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com',
apiId: 'xxxxxxxx' },
body: null,
isBase64Encoded: false }

Lambda関数のコードを修正

event.queryStringParameters 経由でリクエストパラメーターを取得できるようなのでLambda関数のコードを以下のように修正します。

exports.handler = async (event) => {
  console.log(event)
  console.log(process.env)

  let name = 'no name'
  if (event.queryStringParameters && event.queryStringParameters.name) {
    name = event.queryStringParameters.name
  }
  const response = {
    statusCode: 200,
    body: `Hello ${name}`,
  }
  return response
}

APIを呼び出します。

$ curl https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/message?name=wakuwaku
Hello wakuwaku

Lambda関数内でリクエストパラメータを取得できたことを確認できました。

補足

料金について

リクエスト数、実行時間、割り当てたメモリサイズに応じて課金されます。

実際の開発

今回は、雰囲気をつかむために管理画面で操作しました。

実際の開発では、 Serverless FrameworkAWS Serverless Application Model(SAM) などが利用されることが多いです。

各種制限

以下のような利用上の制限がいくつかあります。

  • 関数のタイムアウト時間
  • デプロイパッケージの容量

AWS Lambda の制限

エラー時のリトライ

タイムアウトなどで失敗した場合のリトライ動作は、Lambda関数の呼び出し方法で異なります。

  • ストリームベースではないイベントソース
    • 同期呼び出し
      • e.g.
        • API Gateway(デフォルト動作)
        • Alexa
      • 呼び出し側(アプリ)にエラーを返す。必要があれば、アプリでリトライを実装する。
    • 非同期呼び出し(キューイングされてから実行)
      • e.g.
        • API Gateway(ヘッダでEvent指定時)
        • CloudWatch Events
        • S3
      • 最大2回自動的に再試行(つまり、合計3回実行される可能性がある)
  • ストリームベースのイベントソース
    • e.g.
      • DynamoDBとLambdaを連携する場合
    • データの有効期限が切れるか処理が成功するまで無限にリトライ

AWS Lambda 再試行動作

ドキュメント