AWS CDK (Python) を使ってAPI Gateway + LambdaでPOSTを受け取る


AWS CDKとは大雑把に言うと、AWS上で構築するアプリケーションの設計書(CloudFormation)をプログラミング言語で書いてしまおうというもの。
本記事では、POSTされたJSONをAPI Gatewayを通してLambdaで処理するという単純な流れをPythonを用いて実装します。
AWS CDKを使えるようにするための設定は、以下の公式ドキュメント等を参照のこと:

手順

まず適当なディレクトリを作り、以下のcdk.jsonを作成します。

cdk.json
{
  "app": "python3 app.py"
}

次にそのディレクトリ内に新しいディレクトリ(例えばlambda)を作り、その中にLambdaの関数を作ります(ここではwebhook.py)。単純に、リクエストボディ部のJSONをそのまま返すだけの関数です。

lambda/webhook.py
import json

def handler(event, content):
    try:
        body = event.get("body")
        print(body)
        status_code = 200
    except Exception as e:
        status_code = 500
        body = {"description": str(e)}
    return {
        "statusCode": status_code,
        "headers": {
            "Content-Type": "text/plain"
        },
        "body": json.dumps(body)
    }

最後に元のディレクトリに戻り、本丸のアプリを定義していきます(app.py)。

app.py
import os
from aws_cdk import (
    core,
    aws_lambda as _lambda,
    aws_apigateway as apigw
)

class PrintPostStack(core.Stack):

    def __init__(self, scope: core.App, name: str, **kwargs) -> None:
        super().__init__(scope, name, **kwargs)

        lambda_func = _lambda.Function(
            self, "PrintPostFunc",
            code=_lambda.Code.from_asset("lambda"),
            handler="webhook.handler",
            runtime=_lambda.Runtime.PYTHON_3_7,
        )

        api = apigw.RestApi(self, "PrintPostApi")
        api.root.add_method("POST", apigw.LambdaIntegration(lambda_func))

app = core.App()

PrintPostStack(
    app, "PrintPostStack",
    env={
        "region": os.environ["CDK_DEFAULT_REGION"],
        "account": os.environ["CDK_DEFAULT_ACCOUNT"]
    }
)
app.synth()
  • Stackとは構築されるAWSのリソース全体の集合のことを指す用語です。
  • lambda_funcでLambda関数を設定しています。
    • code=_lambda.Code.from_asset("lambda")はLambda関数ファイルがlambdaディレクトリにあるよということ
    • handler="webhook.handler"webhook.pyhandler関数を見てねということ
    • runtime=_lambda.Runtime.PYTHON_3_7はPython3.7を使ってねということ
  • apiでAPI Gatewayを設定しています。
    • api.root.add_method("POST", apigw.LambdaIntegration(lambda_func))でPOSTメソッドを追加、lambda_funcと統合

以上です。あとは下のコマンドでデプロイするだけ。

$ cdk deploy

うまくいくとエンドポイントURLが表示されます。cURLコマンドで適当なJSONをPOSTし、レスポンスを確認してみましょう。

$ curl -X POST \
> -H "Content-Type: application/json" \ 
> -d '{"Key1":"Value1", "Key2":"Value2"}' \
> https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/

"{\"Key1\":\"Value1\", \"Key2\":\"Value2\"}"

上のようにJSONがそのまま返ってきたら成功です。

また、webhook.pyではリクエストボディ部をprint(body)しています。このログは、CloudWatchから確認することができます。AWSのコンソール > サービスから、CloudWatchを見つけてクリックし、ログ > ロググループからPrintPostStackの名前のついたログを見ましょう。以下のようにJSONが表示されているはずです。

以上です!超単純なAPI Gateway + Lambdaを通してAWS CDKを紹介してみました。
以下の公式の例も参考になると思うのでご覧ください。