第1回ではGETはできるようになったのでPOSTやDELETEもやってみた。 amegaeru.hatenablog.jp しかし、ただメソッドを作成すればよい話ではなさそう。。 (´Д`。)
◆問題点
ブラウザのURLから投げられるHTTPリクエストはGETのみのため同じURLではメソッドによる処理の振り分けができない
◆解決案
下記ができそう( ̄ ~  ̄
案1.処理ごとにリソースを分ける
案2.URLの引数に処理用の値を加える
◆実践!
案1.処理ごとにリソースを分ける
1-1.まずはAPIGatewayで処理ごとのリソースとメソッドを作成する。
下記のように作成。
/
create(リソース)
└GET(メソッド)
read(リソース)
└GET(メソッド)
delete(リソース)
└GET(メソッド)
この場合メソッドはすべてGETのためメソッドで処理を分けれないのでLambdaを複数作成する必要がありだるい。。
Lambdaプロキシ統合ではHTTPリクエストを生成してくるので、その中の[resource]は振り分けに使えそう。
HTTPリクエスト { "resource": "/read", "path": "/", "httpMethod": "GET", "headers": { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "accept-encoding": "gzip, deflate, br", ・・・
1-2.Lambdaコード編集
HTTPリクエストから[resource]を取る形に修正
import json import boto3 # DynamoDB クライアントの作成 dynamodb = boto3.client('dynamodb') table_name = 'sample-dynamodb' def lambda_handler(event, context): method = event["resource"] if method == "/create": return create(event, context) elif method == "/read": return read(event, context) elif method == "/update": return update(event, context) elif method == "/delete": return delete(event, context) else: return { "statusCode": 400, "body": json.dumps({"error": "Unsupported method"}) } def create(event, context): id = event["queryStringParameters"]["id"] value = event["queryStringParameters"]["value"] options = { 'TableName': table_name, 'Item': { 'id': {'S': id}, 'value': {'S': value}, } } response = dynamodb.put_item(**options) res = response["ResponseMetadata"]["HTTPStatusCode"] if res == 200: return { "statusCode": 200, "body": json.dumps(response) } else: return { "statusCode": 404, "body": json.dumps({"error": "Item not found"}) } def read(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) } else: return { "statusCode": 404, "body": json.dumps({"error": "Item not found"}) } def delete(event, context): id = event["queryStringParameters"]["id"] options = { 'TableName': table_name, 'Key': { 'id': {'S': id}, } } response = dynamodb.delete_item(**options) res = response["ResponseMetadata"]["HTTPStatusCode"] if res == 200: return { "statusCode": 200, "body": json.dumps(response) } else: return { "statusCode": 404, "body": json.dumps({"error": "Item not found"}) }
1-3.動作確認
下記にブラウザからアクセスして各処理ができることを確認
1.Read
https://bsm44pfp4j.execute-api.ap-northeast-1.amazonaws.com/test/read?id=123
{"Item": {"id": {"S": "123"}, "value": {"S": "test"}}, "ResponseMetadata": {"RequestId": "U4T46FMF6DAHGI6ALDOBUJ1BBBVV4KQNSO5AEMVJF66Q9ASUAAJG", "HTTPStatusCode": 200, "HTTPHeaders": {"server": "Server", "date": "Sun, 07 May 2023 12:32:09 GMT", "content-type": "application/x-amz-json-1.0", "content-length": "48", "connection": "keep-alive", "x-amzn-requestid": "U4T46FMF6DAHGI6ALDOBUJ1BBBVV4KQNSO5AEMVJF66Q9ASUAAJG", "x-amz-crc32": "2920716868"}, "RetryAttempts": 0}}
2.Create
https://bsm44pfp4j.execute-api.ap-northeast-1.amazonaws.com/test/create?id=124&value=test2
{"ResponseMetadata": {"RequestId": "5R4RI8OL791HAD2LSLTPO97NMFVV4KQNSO5AEMVJF66Q9ASUAAJG", "HTTPStatusCode": 200, "HTTPHeaders": {"server": "Server", "date": "Sun, 07 May 2023 12:32:38 GMT", "content-type": "application/x-amz-json-1.0", "content-length": "2", "connection": "keep-alive", "x-amzn-requestid": "5R4RI8OL791HAD2LSLTPO97NMFVV4KQNSO5AEMVJF66Q9ASUAAJG", "x-amz-crc32": "2745614147"}, "RetryAttempts": 0}}
3.Delete
https://bsm44pfp4j.execute-api.ap-northeast-1.amazonaws.com/test/delete?id=124&value=test2
{"ResponseMetadata": {"RequestId": "AS89KR80P3U2RNKKQHP435I3U3VV4KQNSO5AEMVJF66Q9ASUAAJG", "HTTPStatusCode": 200, "HTTPHeaders": {"server": "Server", "date": "Sun, 07 May 2023 12:32:57 GMT", "content-type": "application/x-amz-json-1.0", "content-length": "2", "connection": "keep-alive", "x-amzn-requestid": "AS89KR80P3U2RNKKQHP435I3U3VV4KQNSO5AEMVJF66Q9ASUAAJG", "x-amz-crc32": "2745614147"}, "RetryAttempts": 0}}
※DynamoDB側でも作成、削除されていることを確認
[DynamoDB]-[テーブル]-[sample-dynamodb]-[テーブルアイテムの検索]
.
.
案2.URLの引数に処理用の値を加える
引数にmethodを加える形でやっていきます。
例)https://xxxx.com/test?id=123&method=read
2-1.まずはAPIGatewayで処理を一手に引き受けるメソッドを作成する。
下記のように作成。
/
└GET(メソッド)
2-2.Lambdaコード編集
URLのmethod値をもとに処理を振り分ける形に修正。
import json import boto3 # DynamoDB クライアントの作成 dynamodb = boto3.client('dynamodb') table_name = 'sample-dynamodb' def lambda_handler(event, context): method = event["queryStringParameters"]["method"] if method == "create": return create(event, context) elif method == "read": return read(event, context) elif method == "delete": return delete(event, context) else: return { "statusCode": 400, "body": json.dumps({"error": "Unsupported method"}) } def create(event, context): id = event["queryStringParameters"]["id"] value = event["queryStringParameters"]["value"] options = { 'TableName': table_name, 'Item': { 'id': {'S': id}, 'value': {'S': value}, }, } response = dynamodb.put_item(**options) res = response["ResponseMetadata"]["HTTPStatusCode"] if res == 200: return { "statusCode": 200, "body": json.dumps(response) } else: return { "statusCode": 404, "body": json.dumps({"error": "Item not found"}) } def read(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) } else: return { "statusCode": 404, "body": json.dumps({"error": "Item not found"}) } def delete(event, context): id = event["queryStringParameters"]["id"] options = { 'TableName': table_name, 'Key': { 'id': {'S': id}, } } response = dynamodb.delete_item(**options) res = response["ResponseMetadata"]["HTTPStatusCode"] if res == 200: return { "statusCode": 200, "body": json.dumps(response) } else: return { "statusCode": 404, "body": json.dumps({"error": "Item not found"}) }
2-3.動作確認
下記にブラウザからアクセスして各処理ができることを確認
1.Read
https://bsm44pfp4j.execute-api.ap-northeast-1.amazonaws.com/test?id=123&method=read
{"Item": {"id": {"S": "123"}, "value": {"S": "test"}}, "ResponseMetadata": {"RequestId": "U6AJS5LTQDQHEQKBRCCBMK161NVV4KQNSO5AEMVJF66Q9ASUAAJG", "HTTPStatusCode": 200, "HTTPHeaders": {"server": "Server", "date": "Sun, 07 May 2023 11:01:59 GMT", "content-type": "application/x-amz-json-1.0", "content-length": "48", "connection": "keep-alive", "x-amzn-requestid": "U6AJS5LTQDQHEQKBRCCBMK161NVV4KQNSO5AEMVJF66Q9ASUAAJG", "x-amz-crc32": "2920716868"}, "RetryAttempts": 0}}
2.Create
https://bsm44pfp4j.execute-api.ap-northeast-1.amazonaws.com/test?id=124&value=test2&method=create
{"ResponseMetadata": {"RequestId": "KI4CFMFA205A3NSP0KJP90B2G3VV4KQNSO5AEMVJF66Q9ASUAAJG", "HTTPStatusCode": 200, "HTTPHeaders": {"server": "Server", "date": "Sun, 07 May 2023 11:50:34 GMT", "content-type": "application/x-amz-json-1.0", "content-length": "2", "connection": "keep-alive", "x-amzn-requestid": "KI4CFMFA205A3NSP0KJP90B2G3VV4KQNSO5AEMVJF66Q9ASUAAJG", "x-amz-crc32": "2745614147"}, "RetryAttempts": 0}}
3.Delete
https://bsm44pfp4j.execute-api.ap-northeast-1.amazonaws.com/test?id=124&value=test2&method=delete
{"ResponseMetadata": {"RequestId": "6JK26S8FNN66QR616V9NS32GT7VV4KQNSO5AEMVJF66Q9ASUAAJG", "HTTPStatusCode": 200, "HTTPHeaders": {"server": "Server", "date": "Sun, 07 May 2023 11:51:32 GMT", "content-type": "application/x-amz-json-1.0", "content-length": "2", "connection": "keep-alive", "x-amzn-requestid": "6JK26S8FNN66QR616V9NS32GT7VV4KQNSO5AEMVJF66Q9ASUAAJG", "x-amz-crc32": "2745614147"}, "RetryAttempts": 0}}
※DynamoDB側でも作成、削除されていることを確認
[DynamoDB]-[テーブル]-[sample-dynamodb]-[テーブルアイテムの検索]
◆結論
案2のほうがあれこれ作らなくてよいからいいかなと思いました。インフラ目線・・・
◆感想
HTTP APIがないときはこんな検討していたのか、そもそもこんなことしないのか。。。
まぁいい勉強になったヾ(o´∀`o)ノ
put_itemだけJSONの中身が違うのがはまった、、、