あめがえるのITブログ

頑張りすぎない。ほどほどに頑張るブログ。

ブラウザのURLからAPI Gateway(REST API)+Lambda(Python)経由でDynamoDBを操作してみた 第1回

ブラウザからいろいろな操作ができると便利なので試しにDynamoDBを操作する仕組みを作ってみた。※タイトルが長い。。

◆やること

ブラウザのURL(https://xxx.com/[resource]?[key]=[value]のような形)でAPI Gateway(REST API)に接続し、バックエンドのLambda(Python)からDynamoDBに接続する。
※今回はDynamoDBからデータを取得するまでを実施する。

構成

◆実践!

1.IAMポリシー作成
 1-1.[IAM]-[ポリシー]-[ポリシー作成]
 1-2.JSONに下記を入力

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1428341300017",
      "Action": [
        "dynamodb:DeleteItem",
        "dynamodb:GetItem",
        "dynamodb:PutItem",
        "dynamodb:Query",
        "dynamodb:Scan",
        "dynamodb:UpdateItem"
      ],
      "Effect": "Allow",
      "Resource": "*"
    },
    {
      "Sid": "",
      "Resource": "*",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Effect": "Allow"
    }
  ]
}

 1-3.確認して作成画面が表示されたら下記を入力
  ・ポリシー名:lambda-dynamo-policy
  ・説明:空白
 1-4.[ポリシーの作成]をクリック

2.ロール作成
 2-1.[IAM]-[ロール]-[ロールを作成]
 2-2.信頼されたエンティティを選択が表示されたら下記を入力
  ・信頼されたエンティティタイプ:AWSのサービス
  ・ユースケース:Lambda
 2-3.[次へ]をクリック
 2-4.許可を追加が表示されたら[lambda-dynamo-policy]を選択
 2-5.[次へ]をクリック
 2-6.ロール名は[lambda-dynamo-role]を入力し、[ロールを作成]をクリック

3.DynamoDBテーブル作成
 3-1.[DynamoDB]-[テーブル]-[テーブルの作成]
 3-2.テーブルの作成画面が表示されたら下記を入力
  ・テーブル名:sample-dynamodb
  ・パーティションキー:id
 3-3.[テーブルの作成]をクリック

4.DynamoDB項目作成
 4-1.[DynamoDB]-[テーブル]-[sample-dynamodb]
 4-2.[アクション]-[項目を作成]
 4-3.下記を入力
  ・id:123
  ・value:test ※[新しい属性の追加]-[文字列]で追加して入力する

5.Lambda関数作成
 5-1.[Lambda]-[関数]-[関数の作成]
 5-2.関数の作成画面が表示されたら下記を入力
  ・一から作成:✅
  ・関数名:sample-function
  ・ランタイム:Python3.10
  ・実行ロール:既存のロールを使用する
  ・既存のロール:lambda-dynamo-role
 5-3.[関数の作成]をクリック
 5-4.コードに下記を入力
  ※POSTやPUT、DELETEもあるが今回はGETのみ使用

import json
import boto3

# DynamoDB クライアントの作成
dynamodb = boto3.client('dynamodb')
table_name = 'sample-dynamodb'


def lambda_handler(event, context):
    method = event["httpMethod"]
    
    if method == "GET":
        return get(event, context)
    elif method == "POST":
        return post(event, context)
    elif method == "PUT":
        return put(event, context)
    elif method == "DELETE":
        return delete(event, context)
    else:
        return {
            "statusCode": 400,
            "body": json.dumps({"error": "Unsupported method"})
        }
        
def get(event, context):
    id = event["queryStringParameters"]["id"]
    options = {
        'TableName': table_name,
        'Key': {
            'id': {'S': id},
        }
    }
    response = dynamodb.get_item(**options)
    
    if 'Item' in response:
        return {
            "statusCode": 200,
            "body": json.dumps(response[Item])
        }
    else:
        return {
            "statusCode": 404,
            "body": json.dumps({"error": "Item not found"})
        }

6.Lambdaテスト
 6-1.作成したLambda関数を選択し、[Test]をクリック
 6-2.テストイベントを設定が表示されたら下記を入力
  ・新しいイベントを作成:✅
  ・イベント名:MyEvent
  ・イベントJSON:下記を入力

{
    "httpMethod": "GET",
    "queryStringParameters": {
        "id": "123"
    }
}

 6-3.[Test]をクリック
 6-4.下記のように返答が返ってくることを確認

Response
{
  "statusCode": 200,
  "body": "{\"Item\": {\"id\": {\"S\": \"123\"}, \"value\": {\"S\": \"test\"}}, \"ResponseMetadata\": {\"RequestId\": \"4706DNS6IB93JOE09NC25FEFN3VV4KQNSO5AEMVJF66Q9ASUAAJG\", \"HTTPStatusCode\": 200, \"HTTPHeaders\": {\"server\": \"Server\", \"date\": \"Sun, 07 May 2023 08:03:42 GMT\", \"content-type\": \"application/x-amz-json-1.0\", \"content-length\": \"48\", \"connection\": \"keep-alive\", \"x-amzn-requestid\": \"4706DNS6IB93JOE09NC25FEFN3VV4KQNSO5AEMVJF66Q9ASUAAJG\", \"x-amz-crc32\": \"2920716868\"}, \"RetryAttempts\": 0}}"
}

7.API Gateway作成
 7-1.[API Gateway]-[REST API]内の[構築]をクリック
 7-2.[新しいAPI]を選択し、下記を入力
  ・API名:SampleAPI
  ・説明:空白
  ・エンドポイントタイプ:リージョン
 7-3.[APIの作成]をクリック
 7-4.[アクション]プルダウンから[メソッドの作成]を選択
 7-5.追加されたプルダウンから[GET]を選択
 7-6.[GET]の隣の✅をクリック
 7-7.右ペインに/ - GET - セットアップが表示されたら下記を入力
  ・統合タイプ:Lambda 関数
  ・Lambdaプロキシ統合の使用:✅
  ・Lambdaリージョン:ap-northeast-1
  ・Lambda関数:sample-function
  ・デフォルトタイムアウトの使用:✅
 7-8.[保存]をクリック
 7-9.[アクション]プルダウンから[APIのデプロイ]を選択
 7-10.APIのデプロイウインドウが表示されたら下記を入力
  ・デプロイされるステージ:[新しいステージ]
  ・ステージ名:test
  ・ステージの説明:空白
  ・デプロイメントの説明:空白
 7-11.[デプロイ]をクリック

8.API Gateway動作確認
 8-1.API Gateway-[API]-[sample-api]
 8-2.左ペイン[ステージ]-[test]-[URLの呼び出し]をクリック
 8-3.URLの末尾に[?id=123]を追記
  例)https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/test?id=123
  ※valueが表示されることを確認

◆感想

REST APIだとアプリケーションからの接続を想定していると思われ、ブラウザのURLからだとGETメソッドしか送信できないのでPOSTなどを組み込む場合はAPI GatewayのHTTP APIを使用するのがよいとおもた。※今度やってみよう。。。