AWS Lambda(with AWS CDK)とHonoでサーバーレスなREST APIを構築する
「Hono」という軽量フレームワークを使用して、AWS Lambdaでアプリを動かす方法を紹介しました。まずはディレクトリを作成し、AWS CDKをセットアップしました。次にHonoをプロジェクトに追加し、REST APIを実装しました。また、CDKを使用してAWS Lambdaと関連する設定を行い、デプロイしました。最後に、APIを呼び出してリクエストを送信し、Honoのレスポンスを受け取りました。
目次
どのインフラでも動かすことができる軽量フレームワークの「Hono」をAWS Lambdaで動かしてみました。
HonoアプリとCDKスタックのセットアップ
Docsの説明に従ってセットアップを始めましょう。
まずはディレクトリを作成します。
% mkdir hono-on-aws
% cd hono-on-aws
ディレクトリが空でないと動かない関係から、先にAWS CDKをセットアップしましょう。
% cdk init app -l typescript
その後プロジェクトにHonoを追加します。
% npm i hono
これで最小限の設定が完了です。
HonoでREST APIを実装する
足回りができたので、APIを作りましょう。
まずはディレクトリとファイルを用意します。
% mkdir lambda
% touch lambda/main.ts
lambda/main.ts
に、HonoでAPIを実装しましょう。
import { Hono } from "hono";
import { handle } from "hono/aws-lambda"
const app = new Hono()
app.get('/', c => {
console.log(c)
return c.json({
message: 'Hello hono!'
})
})
app.all('/*', c => {
return c.json({
path: c.req.path,
})
})
export const handler = handle(app)
「Honoで実装したアプリを、hono/aws-lambda
でラップする」ことで、AWS Lambdaのリクエスト・レスポンスとHonoのリクエスト・レスポンスを変換させている様子です。
CDKでAWS LambdaとLambda functions URLの定義を追加する
デプロイするLambda関数も設定しましょう。
lib/hono-on-aws-stack.ts
をこのように変更しました。
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Architecture, FunctionUrlAuthType } from "aws-cdk-lib/aws-lambda";
import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs";
export class HonoOnAwsStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const lambda = new NodejsFunction(
this,
'hono-app',
{
entry: './lambda/main.ts',
handler: 'handler',
architecture: Architecture.ARM_64
}
)
const url = lambda.addFunctionUrl({
authType: FunctionUrlAuthType.NONE,
})
}
}
ドキュメントでは、API Gatewayを用意していましたが、今回はLambdaのFunction URLを使ってみます。
CDKでアプリをデプロイ
あとはcdk deploy
でデプロイします。
Honoアプリのビルドは、aws-cdk-lib/aws-lambda-nodejs
が内部的にESBuildで実施してくれます。
デプロイ前に追加するリソースの確認があります。想定外のリソースが作られていないか確認して、デプロイしましょう。
IAM Statement Changes
┌───┬─────────────────────────┬────────┬─────────────────────────┬──────────────────────────┬───────────┐
│ │ Resource │ Effect │ Action │ Principal │ Condition │
├───┼─────────────────────────┼────────┼─────────────────────────┼──────────────────────────┼───────────┤
│ + │ ${hono-app.Arn} │ Allow │ lambda:InvokeFunctionUr │ * │ │
│ │ │ │ l │ │ │
├───┼─────────────────────────┼────────┼─────────────────────────┼──────────────────────────┼───────────┤
│ + │ ${hono-app/ServiceRole. │ Allow │ sts:AssumeRole │ Service:lambda.amazonaws │ │
│ │ Arn} │ │ │ .com │ │
└───┴─────────────────────────┴────────┴─────────────────────────┴──────────────────────────┴───────────┘
IAM Policy Changes
┌───┬─────────────────────────┬─────────────────────────────────────────────────────────────────────────┐
│ │ Resource │ Managed Policy ARN │
├───┼─────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ + │ ${hono-app/ServiceRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecut │
│ │ │ ionRole │
└───┴─────────────────────────┴─────────────────────────────────────────────────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)
成功すると、CloudFormationのスタックARNが表示されます。
Stack ARN:
arn:aws:cloudformation:us-west-2:1234567890:stack/HonoOnAwsStack/fa5059d0-3f1f-11ee-b0c0-023ce24fc11b
APIをよびだしてみる
デプロイに成功すれば、あとはLambdaの管理画面またはAWS CLIからURLを取得しましょう。
URLに対してリクエストを投げると、Honoで実装したレスポンスを受け取れます。
% curl -XPOST https://123456789abcde.lambda-url.us-west-2.on.aws/test -d '{"hello": "world"}' | jq .
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 34 100 16 100 18 20 22 --:--:-- --:--:-- --:--:-- 42
{
"path": "/test"
}