今から始めるLambda④「API Gatewayと組み合わせる」
はじめに
前回の記事ではLayers
の仕様・作成方法、Lambda
の関数と連携する方法などを紹介しました。
今回はLambda
とAPI Gateway
を連携させてREST API
を作成する方法を紹介します。
参考
以下の記事を参考に進めています。
※一部変更している箇所があります。
Lambda
以下のようなLambda
は作成されているものとします。
ランタイムはNode.js
で、名称はapiFunction
とします。
exports.handler = async (event, context) => {
const response = {
statusCode: 200,
body: JSON.stringify('This fuction is apiFunction2'),
};
context.done(null, response)
};
後々使用するため、下記コマンドでARN
を取得しておくとよいです。
aws lambda list-functions
REST APIの作成
早速REST API
を作成していきます。
名前はTestAPI
とします。
aws apigateway create-rest-api --name TestAPI --description "This is test API"
このコマンドのレスポンスは以下のようになります。
{
"id": "【REST_API_ID】",
"name": "TestAPI",
"description": "This is test API",
"createdDate": "2021-10-21T13:56:55+09:00",
"apiKeySource": "HEADER",
"endpointConfiguration": {
"types": [
"EDGE"
]
},
"disableExecuteApiEndpoint": false
}
この中のREST_API_ID
はこの後も使うので控えておくとよいです。
リソースの確認
作成したREST API
中のリソースを確認します。
aws apigateway get-resources --rest-api-id 【REST_API_ID】
この時点(デフォルト)では/
のみとなっていることが分かります。
{
"items": [
{
"id": "【ROOT_RESOURCE_ID】",
"path": "/"
}
]
}
リソースの追加
ここに/hoge
というリソース(パス)を追加します。
REST_API_ID
と親にしたいリソースのID(ROOT_RESOUCE_ID
)を指定します。
ここに先ほどの/
のリソースIDを指定します。
aws apigateway create-resource --rest-api-id 【REST_API_ID】 --parent-id 【ROOT_RESOUCE_ID】 --path-part "hoge"
再度確認コマンドを打つと、/hoge
が増えていることが分かります。
※以降/hoge
リソースのIDをHOGE_RESOURCE_ID
とします。
Lambdaとの紐付け
冒頭で紹介したLambda
とREST API
の接続を行います。
クライアントからリクエストが届き、レスポンスが返るまでには以下の4フローがあります。
- クライアントから
API Gateway
へリクエストが届く- ここで認証チェックもするらしい
-
API Gateway
がリソースやHTTP Method
に対応したLambda
を呼び出す -
Lambda
からAPI Gateway
へレスポンスを返す -
API Gateway
からクライアントにレスポンスを返す
API Gateway
では、上記の4ステップそれぞれを設定する必要があります。
①Method Request(クライアントから API Gateway へのリクエスト)
今回は認証を通さず、APIKEYも必要とせず、特にリクエストパラメータもないものとするので
--authorization-type NONE --no-api-key-required --request-parameters {}
というオプションを付けます。
aws apigateway put-method --rest-api-id 【REST_API_ID】 --resource-id 【HOGE_RESOURCE_ID】 --http-method GET --authorization-type NONE --no-api-key-required --request-parameters {}
これがうまくいくと以下のようなレスポンスが返ります。
{
"httpMethod": "GET",
"authorizationType": "NONE",
"apiKeyRequired": false,
"requestParameters": {}
}
②put-integration(API Gateway から Lambda へのリクエスト)
API Gateway
からLambda
を叩きます。
uri
は"arn:aws:apigateway:【REGION】:lambda:path/2015-03-31/functions/【Lambdaの関数のARN】/invocations"
の形式となっているので、以下のようにオプションを指定します。
aws apigateway put-integration --rest-api-id 【REST_API_ID】 --resource-id 【HOGE_RESOURCE_ID】 --http-method GET --integration-http-method POST --type AWS --uri "arn:aws:apigateway:【REGION】:lambda:path/2015-03-31/functions/【Lambdaの関数のARN】/invocations"
うまくいくと以下のレスポンスが返ります。
{
"type": "AWS",
"httpMethod": "POST",
"uri": "arn:aws:apigateway:【REGION】:lambda:path/2015-03-31/functions/【Lambdaの関数のARN】/invocations",
"passthroughBehavior": "WHEN_NO_MATCH",
"timeoutInMillis": 29000,
"cacheNamespace": "kp0l6p",
"cacheKeyParameters": []
}
③put-integration-response(Lambda から API Gateway へのレスポンス)
返却するレスポンスのフォーマットを指定します。
ここでいうところの{"application/json": ""}
です。
aws apigateway put-integration-response --rest-api-id 【REST_API_ID】 --resource-id 【HOGE_RESOURCE_ID】 --http-method GET --status-code 200 --response-templates '{"application/json": ""}'
うまくいくと以下のレスポンスが返ります。
{
"statusCode": "200",
"responseTemplates": {
"application/json": null
}
}
④put-method-response(API Gateway からクライアントへのレスポンス)
今回はLambda
からのレスポンスをAPI Gateway
はそのまま返すイメージなので、③とほぼ似たようなコマンドになります。
aws apigateway put-method-response --rest-api-id 【REST_API_ID】 --resource-id 【HOGE_RESOURCE_ID】 --http-method GET --status-code 200 --response-models '{"application/json": "Empty"}'
パーミッション設定
API Gateway
がLambda
を実行できるように権限を設定します。
--statement-id
は任意の値、--source-arn
は "arn:aws:execute-api:【REGION】:【ACCOUNT_ID】:【REST_API_ID】/*/【HTTPメソッド】/【リソース名】"
の形式になります。
aws lambda add-permission --function-name apiFunction --statement-id api_lamda_test --action "lambda:InvokeFunction" --principal apigateway.amazonaws.com --source-arn "arn:aws:execute-api:【REGION】:【ACCOUNT_ID】:【REST_API_ID】/*/GET/hoge"
これで一通りの設定は完了です。
続いてテストをしてみましょう。
テスト実行
test-invoke-method
で検証ができます。
aws apigateway test-invoke-method --rest-api-id 【REST_API_ID】 --resource-id 【HOGE_RESOURCE_ID】 --http-method GET --path-with-query-string ''
statusCode=200
で返ってくればOKです。
デプロイ
実際に作成したREST API
を適用(デプロイ)します。
この時、ステージ名を指定してデプロイを行う必要があります。
※このステージ名もREST API
のパスに含まれる。
aws apigateway create-deployment --rest-api-id 【REST_API_ID】 --stage-name test --stage-description "This is a test api" --description "API Gateway to Lambda Test"
デプロイ情報、ステージ情報の取得
以下のコマンドを叩いて、先ほど入力した情報が出力されていれば成功です。
aws apigateway get-deployments --rest-api-id 【REST_API_ID】
aws apigateway get-stages --rest-api-id 【REST_API_ID】
ブラウザから検証
REST API
のリンクは"https://【REST_API_ID】.execute-api.【REGION】.amazonaws.com/【ステージ名】/【リソース名】"
となります。
以下のリンクをブラウザから叩いてみて、テスト時と同じレスポンスが返って来れば成功です。
https://【REST_API_ID】.execute-api.【REGION】.amazonaws.com/test/hoge
後片付け
最後に今回作成したREST API
の後片付けを行います。
API Gateway
やLambda
には無料枠がありますが、攻撃を受けたりしてリクエスト回数が嵩むと料金が発生する可能性があるので、必ず行っておきましょう。
REST_API_ID
を指定して削除を行います。
aws apigateway delete-rest-api --rest-api-id 【REST_API_ID】
先ほどのリンクを叩いて、表示されなくなればOKです。
まとめ
今回はAPI Gateway
とLambda
との接続方法について紹介しました。
今回はGET
リクエストでしたが、POST
リクエストを作成したい場合も手順はほとんど同じで、put-method
の時のオプション--http-method
がPOST
になったり、パーミッションの--source-arn
中のGET
がPOST
になっていたりと、一部オプションが変わるだけです。
ここにさらにCognito
を加えての認証や、Aurora
やDynamoDB
を絡めたデータのやりとりを加えることで、一般的なREST API
を作成することができます。
その内容については別記事としたいと思います。
今回の内容が役立ちましたら幸いです。
Discussion