はじめに
AWSにて、Lambda Web Functionsがリリースされました。
Lambdaが3つに分割されたようです。
- Lambda Event Functions
- Lambda Web Functions
- Lambda MicroVMs
今回は、Lambda Web Functionsについて触れてみます。
コードをイベントハンドラーに書き直さずに標準の HTTP ウェブアプリケーションを Lambda で実行できる新しいフォームファクター
と記載されていますが、普段Lambdaを触らない人にとってはイメージが湧きませんよね。
少し概要を調べつつ整理していきます。
執筆時点では Node.js 24 / Arm64 のみ対応です。
利用可能リージョンも バージニア北部・オハイオ・オレゴン・東京・アイルランド の5つに限られます。
概要
従来のNode.js + Expressだと、以下の様にAPIを作成するはずです。
import express from 'express';
const app = express();
app.get('/users', (req, res) => {
res.json({ users: ['田中', '鈴木'] });
});
app.post('/users', (req, res) => {
res.json({ message: '登録しました' });
});
app.listen(3000);
ですが、LambdaでAPIを作成する際は、ハンドラーに書き換えなければいけませんでした。
// 従来のLambda(Event Functions)
export const handler = async (event) => {
// どのURLに来たのか自分で判定する
if (event.path === '/users' && event.httpMethod === 'GET') {
return {
statusCode: 200,
body: JSON.stringify({ users: ['田中', '鈴木'] })
};
}
if (event.path === '/users' && event.httpMethod === 'POST') {
return {
statusCode: 200,
body: JSON.stringify({ message: '登録しました' })
};
}
return { statusCode: 404, body: 'Not Found' };
};
更に言うと、Lambdaはサーバーではなく、「イベントを受け取って1回動いて終わる関数」でした。
Expressのコードをそのまま使えるようにする変換ライブラリー(アダプター)を使用することもできるのですが、ライブラリーを挟む事によって挙動が変わったりすることもあったそうです。
ですが、Lambda Web Functionsが登場して、ハンドラーに書き換える必要が無くなったわけです。
import express from 'express';
const app = express();
const [host, port] = process.env.AWS_LAMBDA_HTTP_ENDPOINT.split(':');
app.get('/users', (req, res) => {
res.json({ users: ['田中', '鈴木'] });
});
app.post('/users', (req, res) => {
res.json({ message: '登録しました' });
});
app.listen(port, host); // ← ここだけ変わった
Next.jsやExpress、Hono、Fastifyも対応しています
更に、従来は同時アクセス数の分だけ実行環境が立ち上がる仕組みでした。Lambda Web Functionsでは1つの実行環境が最大128リクエストを同時に処理するため、暖まった実行環境を共有できます。
DBクエリや外部API呼び出しの待ち時間はCPUをほとんど消費しないので、コストが下がる点もメリットです。
とりあえず触ってみる
AWSが公式で用意しているサンプルを動かします。
aws lambda-web deploy --name hello-world --hello-world --region ap-northeast-1
URLが返ってくるので、叩いてみます。
curl https://xxxxxxxxxxxx.xxx.lambda-web.ap-northeast-1.on.aws
以下が返ってきたらOKです。
{"message":"Hello from Lambda Web!","path":"/"}
無事にLambda Web Functionsのサンプルが作成されました。
次に、Expressアプリを用意してみます。
mkdir lambda-web-sample && cd lambda-web-sample
npm init -y
npm install express
package.jsonに"type": "module"を追加します。
{
"name": "lambda-web-sample",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "module",
"dependencies": {
"express": "^5.3.0"
}
}
index.jsも作成します。
import express from 'express';
const app = express();
app.use(express.json());
const [host, port] = process.env.AWS_LAMBDA_HTTP_ENDPOINT.split(':');
app.get('/users', (req, res) => {
res.json({ users: ['田中', '鈴木'] });
});
app.post('/users', (req, res) => {
res.json({ message: '登録しました', received: req.body });
});
app.listen(port, host);
そのままデプロイします。
aws lambda-web deploy --name my-web-app --code . --region ap-northeast-1
URLが返ってくるので、また叩いてみます。(/users を忘れずに)
curl https://xxxxxxxxxxxxx.xxx.lambda-web.ap-northeast-1.on.aws/users
レスポンスが返ってくれば成功です!
{"users":["田中","鈴木"]}
POSTも確認します。
curl -X POST https://xxxxxxxxxxxxx.xxx.lambda-web.ap-northeast-1.on.aws/users \
-H "Content-Type: application/json" \
-d '{"name":"山田"}'
こっちも成功です。
{"message":"登録しました","received":{"name":"山田"}}
以下のコマンドで削除可能です。
aws lambda-web delete-web-function --function-name my-web-app --region ap-northeast-1
最後に
サーバーレスで環境構築に手間取らない為、シンプルなAPIを作成する際には最適ですね。
CloudFrontとも相性が良く、OACを使用して、エンドポイントを公開せずに、CloudFront経由のアクセスのみに限定できるので、サーバーレスアプリの構築が楽になりそうです。