API Gateway + Lambda + Rust で開発する (2021-01)
まとめ
- netlify_lambda を使う
- Lambda の Docker イメージサポートを利用する
- aws-lambda-rie-gateway を使う
この構成で Slack の interactive message や block kit で遊んだサンプルがこれ https://github.com/eagletmt/misc/tree/master/rust/slack-slash-command-sample
Rust 向けの Lambda Runtime
lambda-runtime という準(?)公式の crate がある https://github.com/awslabs/aws-lambda-rust-runtime が、リリースが滞っている。 現在リリースされている中での最新版では async/await の対応すら入っておらず、現在の Rust では正直使い物にならないレベルである。 master には async/await の対応が入ってるのでそれを使うという手もあるが、痺れを切らした Netlify の方が未マージの PR も一部取り込みつつ netlify_lambda という crate でリリースしている https://github.com/awslabs/aws-lambda-rust-runtime/issues/274 。 この netlify_lambda には v0.2 で Tokio v1.0 対応も入っている。 なので現時点では netlify_lambda を利用するのが一番手軽な上にコミュニティの恩恵を受けやすいと思われる。
Lambda の Docker イメージサポート
最初にこのリリースを見たときは zip が Docker イメージに変わっただけくらいの認識だったが、公式に提供されている public.ecr.aws/lambda/provided:al2 等のイメージには aws-lambda-rie というバイナリが含まれており、手元で Lambda を起動するのが手軽になっている点が非常に価値が高い。 https://docs.aws.amazon.com/lambda/latest/dg/images-create.html
これをベースイメージとして Docker イメージを作ることで、手元で docker run -p 9000:8080 my-awesome-app
で起動すると curl -XPOST http://localhost:9000/2015-03-31/functions/function/invocations -d '{}'
で Lambda のハンドラを動かすことができる https://docs.aws.amazon.com/lambda/latest/dg/images-test.html 。
これまでも Lambda にアップロードする zip を作るときにはどうせ Docker を使ってビルドしていたわけだし、開発やデプロイのことだけを考えれば Lambda の Docker イメージサポートを利用しない理由は無い気がする。 AWS CDK も既にこの機能をサポートしている。
手元での API Gateway 開発
API Gateway + Lambda で API サーバを作るときにも aws-lambda-rie のおかげで curl で API Gateway のペイロードを流せば手元で動作確認ができる。 しかしその API Gateway は別のマイクロサービスだったりフロントエンドの JS だったりから呼ばれて使われることが多く、それらとの連携も合わせて手元で動作確認したい。 そこで普通の HTTP リクエストを API Gateway 用のペイロードに変換して aws-lambda-rie のエンドポイントに流すだけの小さいツール https://github.com/eagletmt/aws-lambda-rie-gateway を書いてみたところ、だいぶ便利になった。
cargo watch --shell 'docker build -t handler:dev . && docker run -p 9000:8080 handler:dev
を起動しておけばコードを変更するたびに Docker イメージがリビルドされ、普通の HTTP リクエストでアクセスできる状態で開発できる。
普通の HTTP リクエストを処理できるので Slack アプリ開発のようなときには ngrok のプロキシ先にも指定できる。
aws-lambda-rie-gateway はとりあえず自分が必要になった範囲しかサポートしてないけど、API Gateway v1 (REST API) のサポートも入れたりしていくと結構実用的なツールになるかもしれない。
Lambda の Docker イメージサポートと aws-lambda-rie に感謝。