API Gateway + Lambda + Rust で開発する (2021-01)

まとめ

この構成で 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 のおかげで curlAPI 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 に感謝。