- LocalStackを用いて、DynamoDBにデータ登録を行うAPIをAPI Gateway + Lambdaで作成する方法についてメモする。
LocalStack 準備
- こちらの手順でDocker LocalStack環境を準備しておく。
Dynamo DB 準備
-
テーブル(
sample-table
)作成aws dynamodb create-table --table-name sample-table --attribute-definitions AttributeName=Data,AttributeType=S --key-schema AttributeName=Data,KeyType=HASH --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 --endpoint-url=http://localhost:4569 --profile localstack { "TableDescription": { "AttributeDefinitions": [ { "AttributeName": "Data", "AttributeType": "S" } ], "TableName": "sample-table", "KeySchema": [ { "AttributeName": "Data", "KeyType": "HASH" } ], "TableStatus": "ACTIVE", "CreationDateTime": "2021-10-09T14:55:59.763000+09:00", "ProvisionedThroughput": { "LastIncreaseDateTime": "1970-01-01T09:00:00+09:00", "LastDecreaseDateTime": "1970-01-01T09:00:00+09:00", "NumberOfDecreasesToday": 0, "ReadCapacityUnits": 1, "WriteCapacityUnits": 1 }, "TableSizeBytes": 0, "ItemCount": 0, "TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/sample-table" } }
-
動作確認(データ登録)
aws dynamodb put-item --table-name sample-table --item={\"Data\":{\"S\":\"fuga\"}} --endpoint-url=http://localhost:4569 --profile localstack
-
登録データ確認
aws dynamodb scan --table-name sample-table --endpoint-url=http://localhost:4569 --profile localstack { "Items": [ { "Data": { "S": "fuga" } } ], "Count": 1, "ScannedCount": 1, "ConsumedCapacity": null }
-
API Gateway 準備
-
REST API を作成する
-
リソースID(
id
)を控えるaws apigateway create-rest-api --name 'LambdaDynamoDBTestAPI' --endpoint-url=http://localhost:4567 --region us-east-1 --profile localstack { "id": "0157166521", "name": "'LambdaDynamoDBTestAPI'", "createdDate": "2021-10-09T06:01:05.462000+00:00" }
-
-
ルートリソースID(以下
id
)取得aws apigateway get-resources --rest-api-id 0157166521 --endpoint-url=http://localhost:4567 --region us-east-1 --profile localstack { "items": [ { "id": "4739445932", "path": "/", "resourceMethods": { "GET": {} } } ] }
-
子リソース追加
パス名:
lambda_dynamodb_test
リソースID(以下
id
)を控える。aws apigateway create-resource --rest-api-id 0157166521 --parent-id 4739445932 --path-part lambda_dynamodb_test --endpoint-url=http://localhost:4567 --region us-east-1 --profile localstack { "id": "A-Z13318A-Z712", "parentId": "4739445932", "pathPart": "lambda_dynamodb_test", "path": "/lambda_dynamodb_test", "resourceMethods": { "GET": {} } }
-
HTTP POSTメソッド追加
aws apigateway put-method --rest-api-id 0157166521 --resource-id A-Z13318A-Z712 --http-method POST --authorization-type "NONE" --endpoint-url=http://localhost:4567 --region us-east-1 --profile localstack { "httpMethod": "POST", "authorizationType": "NONE" }
Lambda 準備
-
lambda_dynamodb_put_test.py
DynamoDBテーブル
sample-table
にデータを登録する。import boto3 from boto3.session import Session from datetime import datetime session = Session(aws_access_key_id='dummy', aws_secret_access_key='dummy', region_name='ap-northeast-1' ) dynamodb = session.resource( service_name='dynamodb', endpoint_url='http://localhost:4569' ) def lambda_handler(event, context): table = dynamodb.Table('sample-table') data = 'sample_' + datetime.now().strftime('%Y-%m-%d-%H-%M-%S') response = table.put_item( Item={ 'Data': data } ) return response
-
上記ファイルを
lambda_dynamodb_put_test.zip
にzip化する。 -
アップロード
aws lambda create-function --function-name="lambda-dynamodb-put" --runtime=python3.8 --role="arn:aws:iam::123456789012:role/service-role/lambda-sample-role" --handler=lambda_dynamodb_put_test.lambda_handler --zip-file fileb://lambda_dynamodb_put_test.zip --endpoint-url=http://localhost:4574 --profile=localstack
-
起動
aws lambda invoke --cli-binary-format raw-in-base64-out --function-name lambda-dynamodb-put result.log --endpoint-url=http://localhost:4574 --profile=localstack
{"StatusCode": 200}
* 動作確認
```shell
aws dynamodb scan --table-name sample-table --endpoint-url=http://localhost:4569 --profile localstack
{
"Items": [
{
"Data": {
"S": "fuga"
}
},
{
"Data": {
"S": "sample_2021-10-09-06-38-16"
}
}
],
"Count": 2,
"ScannedCount": 2,
"ConsumedCapacity": null
}
※データが追加されている。
API Gateway - Lambda 設定
-
Lambda ARN確認
aws lambda list-functions --endpoint-url=http://localhost:4574 --profile=localstack{ "Functions": [ { "FunctionName": "lambda-dynamodb-put", "FunctionArn": "arn:aws:lambda:us-east-1:000000000000:function:lambda-dynamodb-put", "Runtime": "python3.8", "Handler": "lambda_dynamodb_put_test.lambda_handler", "Timeout": 60, "Version": "$LATEST" } ]}
-
API Gateway - Lambda設定
aws apigateway put-integration --rest-api-id 0157166521 --resource-id A-Z13318A-Z712 --http-method POST --type AWS_PROXY --integration-http-method POST --uri arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:000000000000:function:lambda-dynamodb-put/invocations --passthrough-behavior WHEN_NO_MATCH --endpoint-url=http://localhost:4567 --region us-east-1 --profile localstack { "type": "AWS_PROXY", "httpMethod": "POST", "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:000000000000:function:lambda-dynamodb-put/invocations", "integrationResponses": { "200": { "statusCode": 200, "responseTemplates": { "application/json": null } } }}
-
設定デプロイ
aws apigateway create-deployment --rest-api-id 0157166521 --stage-name test --endpoint-url=http://localhost:4567 --region us-east-1 --profile localstack{ "id": "1850348379", "description": "", "createdDate": "2021-10-09T06:43:04.032000+00:00"}
動作確認
- APIリクエスト
POST /restapis/0157166521/test/_user_request_/lambda_dynamodb_test HTTP/1.1
Host: localhost:4567
Content-Type: application/json
Content-Length: 2
{}
- APIレスポンス
{"ResponseMetadata": {"RetryAttempts": 0, "HTTPStatusCode": 200, "RequestId": "9f2c5ca3-6187-4d92-811d-5cd62c5f5289", "HTTPHeaders": {"x-amzn-requestid": "9f2c5ca3-6187-4d92-811d-5cd62c5f5289", "content-length": "2", "access-control-allow-methods": "HEAD,GET,PUT,POST,DELETE,OPTIONS,PATCH", "server": "BaseHTTP/0.3 Python/2.7.13, Jetty(8.1.12.v20130726)", "x-amz-crc32": "2745614147", "date": "Sat, 09 Oct 2021 06:44:22 GMT", "access-control-allow-origin": "*", "access-control-allow-headers": "authorization,content-type,content-md5,x-amz-content-sha256,x-amz-date,x-amz-security-token,x-amz-user-agent", "content-type": "application/x-amz-json-1.0"}}}
- DynamoDB登録データ確認
aws dynamodb scan --table-name sample-table --endpoint-url=http://localhost:4569 --profile localstack
{
"Items": [
{
"Data": {
"S": "fuga"
}
},
{
"Data": {
"S": "sample_2021-10-09-06-38-16"
}
},
{
"Data": {
"S": "sample_2021-10-09-06-44-22"
}
}
],
"Count": 3,
"ScannedCount": 3,
"ConsumedCapacity": null
}
※データが追加されている。