24 日目!
世の中はクリスマスイブ!
ということで、今日は、API Gateway から、昨日作った AWS Lambda 関数をつなぎます。
もちろん、AWS CLIで。
24日目の要約
API!
AWS CLI の準備
このあたりをみて、好きなバージョンとお使いのOSにあった環境設定をしてくださいね。
なんなら、 AWS CloudShell で実行するのも楽でよいと思います。
この記事シリーズは、AWS CloudShell で実行し、実行例を載せています。
バージョン1
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv1.html
バージョン2
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2.html
概要
API Gateway を作って、リクエストを受けたら Lambda 関数に処理させます。
さあ、やってみよう!
今回は API Gateway の REST API を作っていきます。
API Gateway の各要素を以下の図で確認します。
API を作成する
まずは、APIそのものを作成します。今回は REST API を作成するので、apigateway create-rest-api
コマンドを実行します。
aws apigateway create-rest-api --name adventcalendar2021
APIの作成に成功すると、以下のような json が返るので id の値を確認しておきます。
{
"id": "u8********",
"name": "adventcalendar2021",
"createdDate": "2021-12-23T16:08:10+00:00",
"apiKeySource": "HEADER",
"endpointConfiguration": {
"types": [
"EDGE"
]
},
"disableExecuteApiEndpoint": false
}
今回はリソースを作らない(デフォルトで作られる"/"を使う)ので、"/" の ID を確認しておきます。apigateway get-resources
コマンドを実行します。
aws apigateway get-resources --rest-api-id <API の ID>
無事に取得できると、以下のような json が返るので id を確認しておきます。
この id は リソースの ID です。
{
"items": [
{
"id": "g8********",
"path": "/"
}
]
}
GET メソッドリクエストを定義する
ここからは、各要素を順々に作っていきます。
一つ目は、クライアントからのリクエストを受け付けるための GET メソッドを apigateway put-method
コマンドで作っていきます。
aws apigateway put-method \
--rest-api-id <API の ID> \
--resource-id <リソース のID> \
--http-method GET \
--authorization-type NONE \
--no-api-key-required \
--request-parameters {}
作成に成功すると以下のような json が返ります。
{
"httpMethod": "GET",
"authorizationType": "NONE",
"apiKeyRequired": false,
"requestParameters": {}
}
API Gateway から Lambda への統合リクエストを定義する
2つ目は、API Gateway から Lambda 関数へのリクエストを定義しますが、まずは、Lambda 関数の ARN を確認します。
Lambda 関数のARN を確認する
Lambda 関数の情報を取得する lambda get-function
コマンドで ARN を確認することができます。
aws lambda get-function --function-name adventcalendar2021
取得できると、以下のような json が返るので、FunctionArn の値を確認します。
{
"Configuration": {
"FunctionName": "adventcalendar2021",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:************:function:adventcalendar2021",
"Runtime": "python3.8",
(以下、省略)
API Gateway から Lambda へのリクエストを定義する
FunctionArn の値が確認できたら、apigateway put-integration
コマンドで API Gateway から Lambda 関数へのリクエストを定義します。
uri
に指定する形式は、arn:aws:apigateway:<リージョン>:lambda:path/2015-03-31/functions/<Lambdaの関数のARN>/invocations
です。
aws apigateway put-integration \
--rest-api-id <API の ID> \
--resource-id <"/" のID> \
--http-method GET \
--integration-http-method POST \
--type AWS \
--uri arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/<Lambdaの関数のARN>/invocations
コマンド実行が正常に完了すると、以下のような json が返ります。
uri
の後程使用しますので、確認しておきます。
{
"type": "AWS",
"httpMethod": "POST",
"uri": "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:************:function:adventcalendar2021/invocations",
"passthroughBehavior": "WHEN_NO_MATCH",
"timeoutInMillis": 29000,
"cacheNamespace": "g8********",
"cacheKeyParameters": []
}
Lambda から API Gateway への統合レスポンスを定義する
Lambda 関数の処理結果(レスポンス)を API Gateway が受け付けるために apigateway put-integration-response
コマンドで定義します。
aws apigateway put-integration-response \
--rest-api-id <API の ID> \
--resource-id <リソース の ID> \
--http-method GET \
--status-code 200 \
--response-templates '{"text/html": ""}'
問題がなければ、以下のような json が返ってきます。
{
"statusCode": "200",
"responseTemplates": {
"text/html": null
}
}
API Gateway からクライアントへのメソッドレスポンスを定義する
最後の定義です。API Gateway からクライアントへのレスポンスを apigateway put-method-response
コマンドで定義します。
aws apigateway put-method-response \
--rest-api-id <API の ID> \
--resource-id <リソース の ID> \
--http-method GET \
--status-code 200 \
--response-models '{"text/html": "Empty"}'
こちらも問題がなければ、以下のような json が返ってきます。
{
"statusCode": "200",
"responseModels": {
"text/html": "Empty"
}
}
これで一連の要素の作成、定義ができました。
Lambda が API Gateway からのリクエストを受けられるように設定する
Lambda 関数が API Gateway からのリクエストを受け付けられるようにパーミッションを追加します。
lambda add-permission
コマンドを実行します。
aws lambda add-permission --function-name adventcalendar2021 \
--statement-id adventcalendar2021-lambda-permission \
--action "lambda:InvokeFunction" \
--principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:ap-northeast-1:<アカウントID>:<API ID>/*/GET/"
問題がなければ、以下のようなパーミッションが埋め込まれた json が返ります。
{
"Statement": "{\"Sid\":\"adventcalendar2021-lambda-permission\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:ap-northeast-1:<アカウントID>:function:adventcalendar2021\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:ap-northeast-1:<アカウントID>:<API ID>/*/GET/\"}}}"
}
API をテストする
各要素の作成や定義、Lambda 関数のパーミッション設定が済んだら、テスト実行してみます。
apigateway test-invoke-method
コマンドを実行します。
aws apigateway test-invoke-method --rest-api-id <API の ID> \
--resource-id <リソースの ID> \
--http-method GET \
--path-with-query-string ''
テストの実行が終わると以下のような json が返ります。
status: 200
が出ていれば特に問題ありません。
また、body
の内容が今回であれば、 Lambda 関数が出力する HTML の内容になっていることを確認します。
{
"status": 200,
"body": ....
(以下、省略)
API をデプロイする
テストも問題がなければ、API を実際に使える状態にするために apigateway create-deployment
コマンドで API をデプロイします。
aws apigateway create-deployment \
--rest-api-id <API の ID> \
--stage-name PROD \
--stage-description "Production" \
--description "Advent Calendar2021 API"
正常にデプロイが完了すると、以下のような json が返ってきます。
{
"id": "ul****",
"description": "Advent Calendar2021 API",
"createdDate": "2021-12-23T16:34:18+00:00"
}
動作確認
API がデプロイできたので、実際に動作確認をします。
curl コマンドを使い、さらに見やすくするために適宜 sed
コマンドで改行を入れていきます。
curl "https://<API の ID>.execute-api.ap-northeast-1.amazonaws.com/PROD/"| sed "s/br>/br>\n/g" | sed "s/<\/h2>/<\/h2>\n/g"
API から正常にレスポンスが返ると、以下のような出力されます。
"<HTML><TITLE>AWS Lambda Environment Information</TITLE><BODY><h1>AWS Lambda Environment Information</h1><h2>AWS Lambda Environmental Variables</h2>
AWS_LAMBDA_FUNCTION_VERSION=$LATEST<br>
(以下省略)
まとめ
昨日作成した Lambda 関数が API Gateway 経由で利用可能になりました。
これでいつでも、 Lambda 自体の各種情報が取得できますね!
さて、明日は最終回。
24日分の内容を振り返りつつ、後片付けをしましょう。