Rustを使ってLambda関数を作成する方法について記載。
事前準備
cargo-lambdaのインストール
Lambdaを操作するツールとしてcargo-lambdaをインストールをします。
これを用いてビルドやデプロイを行います。
cargo install cargo-lambda
zigのインストール
cargo-lambdaではクロスコンパイルのため、内部ではzigというプログラミング言語を使用します。
ZIG_VERSION=0.14.0
curl -k -L https://ziglang.org/download/${ZIG_VERSION}/zig-linux-x86_64-${ZIG_VERSION}.tar.xz -o zig.tar.xz
mkdir -p /opt/zig
tar -xf zig.tar.xz -C /opt/zig --strip-components=1
ln -s /opt/zig/zig /usr/local/bin/zig
rm zig.tar.xz
ソースコード
Lambdaを管理する場合、最小限ではlambda_runtimeクレートを使用して、以下のようになります。
(拡張性を鑑みてかなりファイル分割は多め)
src/main.rs
pub(crate) mod endpoint;
use lambda_runtime::{Error, LambdaEvent, service_fn};
use log::{error, info, warn};
use serde_json::{Value, json};
/// メイン関数。Lambda関数のエントリポイント。
#[tokio::main]
async fn main() -> Result<(), Error> {
env_logger::Builder::from_default_env()
.filter_level(log::LevelFilter::Info)
.init();
info!("Starting Lambda function");
let handler = service_fn(route_request);
lambda_runtime::run(handler).await?;
Ok(())
}
/// ルートリクエストを処理する関数。
///
/// # 引数
/// - `event`: Lambdaイベント。
/// - `context`: Lambdaコンテキスト。
///
/// # 戻り値
/// - HTTPレスポンス。
async fn route_request(event: LambdaEvent<Value>) -> Result<Value, Error> {
let (payload, _) = event.into_parts();
// パスの取得
let path = payload["path"].as_str().unwrap_or("");
let method = payload["httpMethod"].as_str().unwrap_or("");
info!("Received request: path = {}, method = {}", path, method);
let result = match (path, method) {
("/api/system/health", "GET") => endpoint::system::health::get::handle().await,
_ => {
warn!("Unhandled request: path = {}, method = {}", path, method);
Ok(json!({
"statusCode": 404,
"body": "404 Not Found"
}))
}
};
if let Err(ref e) = result {
error!("Error occurred while processing request: {:?}", e);
}
result
}
src/endpoint/mod.rs
pub(crate) mod system;
src/endpoint/system/mod.rs
pub(crate) mod health;
src/endpoint/system/health/mod.rs
pub(crate) mod get;
src/endpoint/system/health/get.rs
use lambda_runtime::Error;
/// システムのヘルスチェックを行うGETリクエストを処理するモジュール。
///
/// このモジュールは、システムの稼働状態を確認するための簡易的なヘルスチェックを提供します.
/// Lambda関数のエントリポイント。
///
/// # 戻り値
/// - HTTPレスポンスを表すJSONオブジェクト。
pub async fn handle() -> Result<serde_json::Value, Error> {
Ok(json!({
"statusCode": 200,
"body": "Health Check OK"
}))
}
ビルド
以下のコマンドでビルドできます。
cargo lambda build --release --target x86_64-unknown-linux-musl
成果物としては backend/target/lambda/<関数名>/bootstrap
に作成されます。
デプロイ
以下のコマンドでデプロイできます。
cargo lambda deploy --region "$REGION" --iam-role "$ROLE_ARN"
関数名は未指定の場合、Cargo.tomlのプロジェクト名が採用されます。