やりたいこと
APIGateWayを使ってURLのGETで呼び出された場合にGETのパラメータを元に、PostgreSQLを実行し値を返却する(JSON)
この構成の場合、EBSやEC2の構成はもったいない。
構成
・AWSGateWay
・Lambda
APIGateWayを作成すると、下記のようなURLが生成される
HTTP API の場合
https://abc123xyz.execute-api.ap-northeast-1.amazonaws.com
GETエンドポイントを /users にした場合:
https://abc123xyz.execute-api.ap-northeast-1.amazonaws.com/users?id=1
REST API の場合 ※ prod はステージ名
https://abc123xyz.execute-api.ap-northeast-1.amazonaws.com/prod/users?id=1
GETパラメータを使うなら:
https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/users?id=10
Lambda内では:
event["queryStringParameters"]["id"]
で取得可能。
import json
import psycopg2
def lambda_handler(event, context):
param = event["queryStringParameters"]["id"]
# パラメータ自体が無い場合
if not params or "id" not in params:
return {
"statusCode": 400,
"body": json.dumps({
"message": "パラメータを設定してください"
}, ensure_ascii=False)
}
conn = psycopg2.connectconnect(
host="your-rds-endpoint",
database="your_database_name",
user="your_username",
password="your_password",
port=5432
)
cur = conn.cursor()
cur.execute("SELECT * FROM table WHERE id=%s", (param,))
result = cur.fetchone()
# データがない場合
if result is None:
return {
"statusCode": 404,
"body": json.dumps({
"message": "データが見つかりません"
}, ensure_ascii=False)
}
return {
"statusCode": 200,
"body": json.dumps(result)
}
LabmdaはRDS接続する場合、RDSと同じVPC内に入れる必要がある
入れる方法
1.AWSコンソール
2.Lambda
3.対象の関数を開く
4.「設定」タブ
5.「VPC」→ 編集
6.VPCを選択
7.サブネットを選択(通常は2つ以上)
8.セキュリティグループを選択
9.保存
セキュリティグループ設定
API Gateway → Lambda → RDS(PostgreSQL) 構成で、
設定が必要なインバウンド/アウトバウンド/付与項目
PostgreSQL(5432)をRDSへ許可
タイプ ポート 宛先
PostgreSQL 5432 sg-rds
RDSのセキュリティグループ(sg-rds)
インバウンド
タイプ ポート ソース
PostgreSQL 5432 sg-lambda
アウトバウンド
通常はデフォルト(全許可)のままでOK
Lambdaに付与するIAMロール
Lambda
実行ロール
AWSLambdaBasicExecutionRole
※用途:CloudWatch Logs へ出力するため
VPCに入れる場合
AWSLambdaVPCAccessExecutionRole
※ENI(ネットワークインターフェース)作成のため
RDS用のIAMは必要?
DBユーザー/パスワードで接続
API GATEWAYで、HTTPAPIを選択する方が効果的
PythonでHTTPレスポンスを返す違和感について
LambdaはWEBサーバではない
Lambdaは:
関数(Function)ですHTTPサーバーではありません。
API GatewayがHTTPを担当
流れ
HTTPリクエスト
↓
API Gateway
↓(JSONに変換)
Lambda
↓(結果を返す)
API Gateway
↓
HTTPレスポンスに変換
Pythonが直接HTTPを返しているわけではない
API GatewayがHTTPに変換している
なぜ statusCode や body があるの?
API Gatewayがこういう形式を期待しているからです:
return {
"statusCode": 200,
"body": "..."
}
これは「HTTPっぽいフォーマット」であって
Lambda自体はHTTPを理解していません。
見せかけているだけなんです。



