本記事の目的
Lambda + API Gatewayで構築した REST API を公開し、Swagger UI によって視覚的にAPIの確認ができるようになることをゴールとします。
なお、フレームワークにはFast APIを使用し、ECRを経由してDockerイメージをLambdaに展開することを想定しています。
AWSの構成は以下の通りです。
背景
現時点で対応する画面が無いREST APIの開発を進めていく上で、クライアントへのAPIの見せ方について検討したところ、Swagger UIを利用できれば、工数をかけずに視覚的な操作を提供できるという結論から、本記事の作成に至りました。
その中で、Lambdaに乗せることを考慮した設定がいくつか必要だったこともあり、誰かのお役に立てれば幸いです。
前提
本記事は、Swagger UIとかLambdaとか名前はわかるけど、あんまり使ったことないしとりあえず構築の仕方だけ知りたい!といったお急ぎの方を想定して作成しています。
そのため、本記事ではAPIのローカル開発環境や詳細な設定値については触れず、APIを公開し、Swagger UIを確認するための手順が主として説明しています。
個々の詳細は追って記事を作成したいと思うだけ思ってます。
手順
- Fast APIでREST APIの作成
- ECRにイメージをプッシュ
- Lambdaでイメージの展開
- API Gatewayのセットアップ
Fast APIでREST APIの作成
Fast APIの立ち上げ手順については割愛し、以下のリポジトリを使用します。
Lambdaに乗せる場合には、以下の点に注意する必要があります。
- openapi_prefixにAPI Gatewayのステージ名を入力する
- Mangumを使用してlambda_handlerを定義する
app = FastAPI(openapi_prefix='/sample/') # ← API Gatewayのステージ名
app.include_router(sample.router)
lambda_handler = Mangum(app) # ← lambda_handlerをMangumを使用して定義する
ポイント① 「openapi_prefixにAPI Gatewayのステージ名を入力する」
API Gatewayを経由してアプリケーションを公開する場合、デフォルトのアプリケーションルートへのURLは、
https://{API Gatewayのドメイン名}/{ステージ名}/
とアプリケーションルートとドメインの間にステージ名が入る構造になっているため、Swagger UIがリクエストするOpenAPIの定義ファイルへのパスとの不整合が発生し、403エラーが発生します。
API Gatewayでは、定義されていないリソースパスへのリクエストを行った場合、「リソースパスが存在しない」という403 HTTPレスポンスが返されます。
"x-amzn-errortype" = "MissingAuthenticationTokenException"
参考
https://repost.aws/ja/knowledge-center/api-gateway-troubleshoot-403-forbidden
これを回避するために、Fast APIクラスの引数で
openapi_prefix='/{ステージ名/'
(デフォルト値は ''
)
を指定してあげることで、正常に表示することができるようになります。
ポイント② 「Mangumを使用してlambda_handlerを定義する」
Lambdaはlambda_handlerという関数がメインメソッドとして機能します。そのため、Fast APIなどで定義したapp.pyなどのメインファイルだけでは直接的に動かすことができません。
そこで、WSGIアプリケーションやASGIアプリケーションを動かすためには専用のアダプターが必要となります。
今回は、ASGIアプリケーションアダプターのMangumを利用してlambda_handlerからアプリケーションへリクエストを流してもらうように設定します。
from mangum import Mangum
lambda_handler = Mangum(app)
ECRにイメージをプッシュ
Dockerfileを定義して、イメージをビルドします。
docker build -t swagger-sample .
管理しやすくするために、作成したイメージにタグ付けをします。
docker tag swagger-sample:latest {アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/swagger-sample:latest
レジストリカタログへプッシュするために、ECRにログインします。
ECRへのイメージのプッシュを許可するポリシーがアタッチされているEC2上で作業をしている場合は、以下のコマンドでログインが可能です。
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin {アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com
最後にプッシュします。
ocker push {アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/swagger-sample:latest
Lambdaでイメージの展開
AWSマネジメントコンソールから、
前段でプッシュしたイメージをコンテナイメージURIとして選択し、Lambda関数を作成します。
API Gatewayのセットアップ
Lambda関数を作成したら、最後の仕上げに移ります。
- 「API Gateway」サービス → 「APIの作成」→ 「REST API」と移動
- API名を入力し他はデフォルト設定のまま、下部の「APIを作成」を押下
- 作成したAPIの詳細画面で、「メソッドを作成」を押下し、以下を設定
- メソッドタイプ:GET (必要に応じて追加)
- 統合タイプ:Lambda関数
- Lambda プロキシ統合:ON
- Lambda関数:前段で作成したLambda関数を選択
- その他:デフォルト(必要に応じて設定)
- 作成したAPIの詳細画面に戻り、「リソースの作成」を押下し以下を設定
- プロキシのリソース:ON
- リソース名:{proxy+}
- 追加された
/{proxy+}
のANYメソッドを押下し、「統合の編集」を押下- 統合タイプ:Lambda関数
- Lambda プロキシ統合:ON
- Lambda 関数:前段で作成したLambda関数を選択
- その他:デフォルト
- 作成したAPIの詳細画面に戻り、「APIをデプロイ」を押下
- 新しいステージを作成し、「デプロイ」
新しいステージを作成する際に、openapi_prefix
の値と一致していることを確認しましょう。
ブラウザからSwagger UIの確認
Fast APIのデフォルト設定では、 /docs
がSwagger UI用のエンドポイントとして定義されています。
そのため、以下のURLで検索をかけることで、Swagger UIが閲覧できるようになっていると思います。
https://{デプロイ時に作成されたAPI Gatewayのエンドポイント(ステージ名を含む)}/docs
まとめ
今回はFast APIを使用したアプリケーションを Lambda + API Gateway で公開し、Swagger UIでAPIを視覚的に確認するという手順の紹介をしました。
Fast APIでは、Swagger UIを標準的に組み込まれており、ちょっとした設定をするだけでSwagger UIでのAPI確認が可能となっています。
Lambda + API Gateway上で公開する場合のポイントとして、
- API Gatewayを介す場合、OpenAPI定義ファイルのデフォルトパスがずれてしまうため、プレフィックスを指定する必要がある
- Fast API上でASGIアプリケーション用アダプタを使用してlambda_handlerメソッドを定義する必要がある
の2点を挙げています。自分のようなAPIもインフラも初心者の方の参考になれば幸いです。
アダプタやCORSの細かい話はまたどこかで取り上げたいと思っています。
最後まで読んでいただきありがとうございました。
参考資料
本記事の作成にあたり、以下の記事を参考にさせていただきました。