【PF-1】APIGateway・Lambda

3 min read読了の目安(約2800字

API構成

以下のようなAPIの構成で作成

 ▼/
  ▼ /ctrl
   ▼ /users
      GET
      OPTIONS
      POST
    ▼/{user_id}
       DELETE
       GET
       OPTIONS
       PATCH

lambdaプロキシ統合の設定

DynamoDBのパーティションキーをuser_idとしたため、lambdaでパスパラメータ(user_id)を利用したかった。
そのため、/ctrl/users/{user_id}直下のメソッドについてはLambdaプロキシ統合を設定した。
パスパラメータはlambdaでは以下のようにして受け取る

def lambda_handler(event, context):
    id = event["pathParameters"]['user_id']
    // ・・・

lambdaプロキシ統合設定時の注意点

lambdaでクライアントリクエストの値を利用する場合

lambdaプロキシ統合を設定しない場合、lambdaではリクエストボディの内容を以下のようにして受け取り、扱うことができる

def lambda_handler(event, context):
    postResponse = table.put_item(
        Item={
            'user_id': event['user_id'],
            'comment': event['comment'],
            'first_name': event['first_name'],
            'last_name': event['last_name'],
            'mail': event['mail']
        }
    )

一方でlambdaプロキシ統合を設定した場合は以下のようにしなければならない

def lambda_handler(event, context):
    postResponse = table.put_item(
        Item={
            'user_id': event['body']['user_id'],
            'comment': event['body']['comment'],
            'first_name': event['body']['first_name'],
            'last_name': event['body']['last_name'],
            'mail': event['body']['mail']
        }
    )

これは、Lambdaプロキシ統合の場合、APIGatewayは、クライアントリクエスト全体をバックエンドLambda関数の入力eventパラメータにマッピングするためである

CORSの有効化

lambdaプロキシ統合を設定しない場合、REST APIリソースでCORSサポートを有効にすることができた。
一方で、lambdaプロキシ統合を設定した場合、レスポンスヘッダに直接書き込む必要がある

return {
        'statusCode': 200,
        'headers': {
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Methods": event['httpMethod']
        },
        'body': json.dumps(・・・)
    }

lambda関数

メソッドごとにlambda関数を用意し、それぞれのlambda関数がDynamoDBのテーブルに登録されたデータを操作する役割を担うようにした。
基本的には開発者ガイドに沿って記述すればよい。
updateのみ注意が必要で以下のように記述した

event_body = json.loads(event['body'])
updateResponse = table.update_item(
Key=partition_key,
UpdateExpression="set first_name=:fn, last_name=:ln, mail=:mail",
ExpressionAttributeValues={
    ':fn': event_body['first_name'],
    ':ln': event_body['last_name'],
    ':mail': event_body['mail']
},
ReturnValues="UPDATED_NEW"
)

APIGatewayから渡されるevent['body']がどうやらstringのようなのでjson.loadsしてやる必要がある。
また、DynamoDBに登録されている値の更新に関しては、UpdateExpressionで更新するDynamoDBテーブルのcolumn名を:xx(xxは任意の文字)に変換してやり、ExpressionAttributeValuesでそれぞれ更新後の値を設定する