はじめに
株式会社マイスター・ギルド新規事業部のヒツジーです。
弊社新規事業部では、新規サービスの立ち上げを目指して
日々、アイディアの検証やプロトタイプの作成などを行っています!
技術の進歩は目覚ましいので、置いてかれないように新しい技術のキャッチアップにもいそしんでいます!
本記事では、FastAPI with Lambda + API Gatewayでサーバレスアプリケーションを作成する方法をご紹介します。
サーバレスアプリケーションには
- サーバーの管理が不要
- 使った分だけの支払いで済む
- 柔軟なスケーラビリティ
といったメリットがあり、新規サービスのプロトタイプ作成に向いていると思います。
本記事の手順通りに手を動かすと、さくっとREST APIを作れるようになりますよ!
やりたいこと
FastAPIで作成したアプリケーションファイルをLambda関数に登録し、API GatewayでLambdaへのルーティングを処理するようにしたい。
これをAPIサーバーとして用意し、フロントエンドからAPIを実行することができるようにしたい。
やることの全体像
1つ1つの手続きは少し面倒で全体像を見失いがちになるので、はじめにやることの全体像をお見せします。
ざっくりいうと、
アプリのファイルをzipファイルに圧縮し、Lambdaにファイルをアップして、API Gatewayの設定をする
だけです。
詳しくは、
- FastAPIのアプリケーションファイルにMangumのハンドラーを設置
- FastAPIのアプリケーションファイルをzip圧縮する
- zipファイルをLambdaにアップロードしてLambda関数を作成し、テストが通るようにする
- 作成したLambda関数へのルーティングをAPI Gatewayで処理するように設定し、REST APIのエンドポイントを発行する
になります。
以下から詳しい手順の説明になります。
FastAPIのアプリケーションファイル
FastAPIのアプリケーションファイルはこちらを利用します。
{domain}/api/hoge
のエンドポイントを叩くと下のスクショのように、{"is_success": true}
が返ってくるようなAPIが実装されています。
(こちらのアプリケーションファイルの詳しい解説はまたどこかの機会にできたらいいなと思っています。)
FastAPIをLambdaで利用するには、Mangumというライブラリーを使う必要があります。
Mangumとは
Mangumは、AWS LambdaでASGIアプリケーションを実行し、Function URL、API Gateway、Application Load Balancer、Lambda Edgeのイベントを処理するためのアダプタです。
Mangumの利用方法
from mangum import Mangum
app = FastAPI()
handler = Mangum(app)
通常利用では、app = FastAPI()
だけでよいですが、LambdaでFastAPIを使えるようにするために、fastapiのインスタンスをmangumのハンドラーに渡す必要があります handler = Mangum(app)
。
mangum の pip installが済んでいない場合は、しておきましょう。
$ pip install mangum
コードベースの準備はこれだけで完了です。
Lambda関数の作成
次はLambda関数を用意します。
- Lambdaのサービスページにアクセスします。
- 関数を作成します。
- 一から作成を選択し、基本的な情報を入力していきます。
- 関数名を入力
- ランタイムは「Python 3.9」を選択
- それ以外はデフォルトのまま(ここはお好みで)
- ページ右下部の「関数の作成」ボタンを押下します。
- 一から作成を選択し、基本的な情報を入力していきます。
これでLambda関数は完成です!
LambdaにFastAPIのアプリケーションファイルをアップロードする
FastAPIのアプリケーションファイルを圧縮し、zipファイルを生成することでLambdaにアップロードすることができるようになります。
ここでは、圧縮の方法とアップロード方法をお見せします。
ファイルのzip圧縮方法
Lambdaにアップロードするファイルはzipファイルでないといけないんですが、そのzipファイル内に含めないといけない情報は以下の2つです。
- アプリケーションファイル
- 各種ライブラリのファイル(pip installしてきたライブラリ)
これらのファイルをzipファイルとして1つにまとめるコマンドは以下のようになります。
$ cd <appフォルダ: clean-architecture-like-fastapi> # root dirに入ります
$ pip install -t ./lib -r ./docker/python/requirements.txt # ライブラリ群をインストールし、libフォルダを作成 & データの格納
$ cd lib # libフォルダ内に入ります
$ zip ../lambda_function.zip -r . # libファイル内のライブラリのファイル群が圧縮され、root dir直下にlambda_function.zipが生成される
$ cd .. # root dirに戻ります
# アプリケーションファイルが多いので以下のようにたくさん追加してます。(アップロードするファイルを一階層上からにすれば、まとめてできるので、実はもっと楽です。)
$ zip lambda_function.zip -u main.py # main.pyファイルをzipファイルに追加
$ zip lambda_function.zip -u __init__.py # __init__.pyファイルをzipファイルに追加
$ zip lambda_function.zip -u -r adapters # adaptersフォルダをzipファイルに追加
$ zip lambda_function.zip -u -r drivers # driversフォルダをzipファイルに追加
$ zip lambda_function.zip -u -r usecase # usecaseフォルダをzipファイルに追加
$ zip lambda_function.zip -u -r entities # entitiesフォルダをzipファイルに追加
$ zip lambda_function.zip -u -r config # configフォルダをzipファイルに追加
-u
タグはアップデートタグで、zipファイルに追加するときに使います。
-r
タグはファルダ内の階層深く全ファイルをzipファイルに追加するときに使います。
これでappフォルダ直下に lambda_function.zip
が生成されたと思います。
lambda_function.zip
ファイル内はこんな感じで各種ライブラリのインストールファイルが含まれてます。
※ zipコマンドが叩けない場合はこちらの記事を参考にインストールしてください。( for Windowsユーザー)
Lambda関数へのファイルアップロードと動作テスト
-
動作確認をするために、テストを作成します。
- 「コード」横の「テスト」をクリック
- 「新しいイベントを作成」にチェック
- イベント名を入力
- テンプレートは「apigateway-aws-proxy」を選択
- イベントJSON内の
"path": "/path/to/resource",
と"httpMethod": "POST",
を"path": "/api/test",
と"httpMethod": "GET",
に変更する。冒頭部と最下部の2か所にあるので注意 - 右上の「保存」ボタンをクリックし、現状を保存する
- 右上の「 テスト」ボタンをクリックし、動作確認
- テストするとおそらくこんなエラーが出ます。これはハンドラーの指定が間違っていることが原因で起きるよくあるエラーです。
{
"errorMessage": "Unable to import module 'lambda_function': No module named 'lambda_function'",
"errorType": "Runtime.ImportModuleError",
...
}
ハンドラーの修正
- コードページを開く
- ランタイム設定のハンドラーを確認すると
lambda_function.lambda_handler
になっている。 - これを「編集」で
main.handler
に修正します。
→main.pyのhandlerをハンドラー指定しています。つまり上で書いたhandler = Mangum(app)
の部分です。
API Gateway側の設定
API Gatewayの設定を行い、Lambda関数へのルーティングを処理できるようにしていきます。
-
API Gatewayのサービスページにアクセス
-
REST APIで新しいAPIを作成
-
アクション→メソッドの作成→Anyを選択
-
/- ANY - セットアップ
-
リソースの設定
-
/{proxy+} - ANY - セットアップ
-
アクション→APIのデプロイ
https://(ここはお見せできない).execute-api.(リージョン).amazonaws.com/dev/api/hoge
からAPIを叩けるようになりました!
最後に
(手順さえ覚えてしまえば、)簡単にREST APIのサーバレスアプリケーションが作成できるようになりました!
FastAPIはさくっとAPIを実装できるので、簡単にアプリを作りたいときには重宝します。
新規サービス開発時にも使えたら使っていきたいと思います!