この記事はマイナビ Advent Calendar 2021の21日目の記事となります。
#目的
AWS Lambda、API Gateway、Amazon RDSを利用して簡易的なサーバーレスAPI(以下、簡易API)を構築します。簡易APIにリクエストを送ると、RDSから値を取得しレスポンスを返すという仕様になります。
#前提・注意事項
- 本ソースコードを試す場合は、APIとして外部公開される危険性を考慮し、DBに機密なデータが無いことを確認の上お試しください。
- 事前にRDSを構築しておく必要があります。今回の記事では詳細は省略しております。
- 認証に関しては、今回説明しておりませんが、IAM認証やCognito認証、API Gateway Lambda オーソライザー等を利用して設定してください。
#手順①Lambda⇔DB連携
###1. Lambda関数作成
-
Lambdaコンソール画面にアクセス
2)「関数の作成」ボタン押下 - 関数設定
オプション:一から作成
関数名:各自命名
ランタイム:Python3.9
アーキテクチャ:arm64
アクセス権限の実行ロール:基本的なLambdaアクセス権限で新しいロールを作成
4) 関数詳細設定
詳細設定を開き「ネットワークを有効化」にチェックを入れ、下記の通り設定する
VPC:DBと同じ
サブネット:DBと同じ
セキュリティグループ:DBと同じ
5)「関数の作成」ボタン押下
ボタン押下後、関数が作成されるまで2~3分ほど時間がかかるため、しばらく待機。
6) app.zipアップロード
下記コマンドを実行し、ローカルでapp.zipファイルを作成後、コードソース内から「アップロード元」→「.zipファイル」→「アップロード」→「app.zip」→「保存」でapp.zipをアップロードする
# pymsqをlローカルにインストール
pip3 install pymysql -t .
# zip化
zip -r app.zip /path/to/workdir/*
7) ディレクトリ構成変更
関数のディレクトリ構成を下記のように変更する
関数名
└pymsql
└PyMySQL-1.0.2.dist-info
import sys
import json
import pymysql
# DB接続情報設定
host = '<DBホスト名>'
user = '<DBユーザー名>'
passwd = '<DBパスワード>'
db_name = '<DB名>'
def lambda_handler(event, context):
try:
# DB接続
conn = pymysql.connect(host = host, user = user, passwd = passwd, db = db_name, connect_timeout = 5)
except Exception as e:
print("error")
print(e)
# カーソル作成
cursor = conn.cursor()
# クエリ
query = "SELECT id, name FROM test_t WHERE id = %s"
# クエリ実行
cursor.execute(query, (event['id']))
# クエリ実行結果取得
result = cursor.fetchall()
return {
'statusCode': 200,
'body': result
}
- 「Deploy」ボタン押下
###2. Lambda関数テスト
- テストイベント作成
下記の通りテストイベント作成し「テスト」ボタン押下
例)
テンプレート:id
名前:test_q
{
"id": 1
}
- 実行結果確認
実行結果を開き、DBから値取得できていることを確認
#手順②API Gateway⇔Lambda連携
###1. 関数のトリガーにAPI Gatewayを設定
- Lambda関数の概要から「トリガーを追加」ボタン押下
- API Gatewayを選択→APIの選択肢から「APIを作成する」を選択
- API情報設定
下記の通りAPI情報を設定し「追加」ボタン押下
・APIタイプ:REST API
・セキュリティ:オープン
▼追加の設定
・API名:自身で分かりやすい名前を指定
・デプロイされるステージ:develop
###2. API Gatewayメソッド作成
- API Gatewayコンソール画面にアクセス
- 上記作成したAPI Gateway選択
- ANYメソッド削除
リソースのANYメソッドを選択したまま「アクション」ボタンを押下し「メソッドの削除」を選択
- 「削除」ボタン押下
アラートで「ANY を削除してよろしいですか?」と表示されたら「削除」ボタン押下 - 「GET」メソッド作成
[リソース]にて「アクション」ボタン押下→「メソッドの作成」選択→プルダウンから「GET」選択→☑マーク押下 - 設定
セットアップ画面にて、下記の通り設定し「保存」ボタン押下
・統合タイプ: Lambda 関数
・Lambda プロキシ統合の使用:チェックなし
・Lambda リージョン:ap-northeast-1
・Lambda 関数:既に作成したLambda関数名
・デフォルトタイムアウトの使用:☑あり
7) 権限追加
アラートで「Lambda 関数に権限を追加する」と表示されたら「OK」ボタン押下
###3. API Gatewayメソッドリクエスト編集
- [リソース]の[GET - メソッドの実行]から[メソッドリクエスト]選択
- [設定]の[認可]のプルダウンから[AWS IAM]を選択
- [設定]の[リクエストの検証]のプルダウンから「クエリ文字列パラメータおよびヘッダーの検証」を選択し☑マーク入れる
- [URL クエリ文字列パラメータ]から「クエリ文字列の追加」選択→「名前:id」を入力→☑マーク入れる
###4. API Gateway統合リクエスト編集
- [リソース]の[GET - メソッドの実行]から[統合リクエスト]選択
- 「マッピングテンプレートの追加」→Content-Typeにapplication/jsonを入力→☑マーク押下
- アラートで「パススルー動作の変更」と表示されたら「はい、この統合を保護します」ボタン押下
- テンプレートのテキストエディタに下記を入力し、「保存」ボタン押下
{
"id" : "$input.params('id')"
}
###5. APIデプロイ
- [リソース]の[アクション]から「APIのデプロイ」押下
アラートで「APIのデプロイ」と表示されたら下記を入力し「デプロイ」ボタン押下
・デプロイされるステージ:develop
・デプロイメントの説明:テスト用Lambda APIのデプロイ
###6. APIテスト