こんにちは、CX 事業本部製造ビジネステクノロジー部の若槻です。
Serverless Express は、AWS Lambda などのサーバーレス環境で Express.js を利用した REST API を構築できるライブラリです。
今回は、Serverless Express + AWS Lambda + API Gateway の構成を AWS CDK でデプロイして作成してみました。
試してみた
パッケージの導入
いくつかのパッケージ npm からインストールして導入します。
Serverless Express
@codegenie/serverless-express
をインストールします。
npm i @codegenie/serverless-express
最近、Serverless Express が CodeGenie に移行したので、古い方のパッケージをインストールしないように注意してください。
その他
express および cors(必要な場合)をインストールします。
npm i express
npm i cors
npm i -D @types/cors
Lambda コード
Lambda ハンドラーのコードです。/companies
パスへの POST メソッドのリクエストのルーティングを設定しています。
src/rest-api-router.ts
import serverlessExpress from '@codegenie/serverless-express';
import cors from 'cors';
import express, { Request, Response } from 'express';
const app = express();
app.use(cors());
app.use(express.json());
app.post('/companies', async (req: Request, res: Response): Promise<void> => {
res.status(201).send({ ...req.body, id: 'c123' });
});
export const handler = serverlessExpress({ app });
CDK コード
AWS Lambda と API Gateway を作成する CDK スタックのコードです。LambdaRestApi
コンストラクトクラスを使用することにより、Lambda プロキシ統合の REST API を作成できます。
lib/cdk-sample-stack.ts
import {
aws_lambda,
aws_lambda_nodejs,
aws_apigateway,
Stack,
Duration,
CfnOutput,
} from 'aws-cdk-lib';
import { Construct } from 'constructs';
export class CdkSampleStack extends Stack {
constructor(scope: Construct, id: string) {
super(scope, id);
/**
* Lambda 関数を作成
*/
const restApiFunc = new aws_lambda_nodejs.NodejsFunction(
this,
'RestApiFunc',
{
architecture: aws_lambda.Architecture.ARM_64,
runtime: aws_lambda.Runtime.NODEJS_20_X,
entry: 'src/rest-api-router.ts',
}
);
/**
* REST API を作成
*/
const restApi = new aws_apigateway.LambdaRestApi(this, 'RestApi', {
handler: restApiFunc,
defaultCorsPreflightOptions: {
allowOrigins: aws_apigateway.Cors.ALL_ORIGINS,
allowMethods: aws_apigateway.Cors.ALL_METHODS,
allowHeaders: aws_apigateway.Cors.DEFAULT_HEADERS,
maxAge: Duration.minutes(5),
}, // Web アプリケーションからの CORS リクエストを許可する場合はこの記述を追加
deployOptions: {
stageName: 'v1', // 既定では "prod" になるため、適切なステージ名に変更
tracingEnabled: true, // AWS X-Ray によるトレースを有効化
},
});
/**
* API Gateway エンドポイント
*/
new CfnOutput(this, 'RestApiEndpoint', {
value: restApi.deploymentStage.urlForPath(),
});
}
}
動作確認
CDK でデプロイした API Gateway のエンドポイントに対して、/companies
パスへの POST メソッドのリクエストを送ると、{"Name":"Hello株式会社","id":"c123"}
というレスポンスが返ってきました。Serverless Express がちゃんと動いているようです。
$ curl -X POST -H "Content-Type: application/json" \
-d '{"Name":"Hello株式会社"}' \
https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/companies
{"Name":"Hello株式会社","id":"c123"}
同じパスでも GET メソッドでリクエストを送ると、Cannot GET /companies
というエラーメッセージが返ってきます。(想定通り)
$ curl -X GET \
https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/companies
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /companies</pre>
</body>
ルーティングを設定していないパスにリクエストを送ると、Cannot POST /employees
というエラーメッセージが返ってきます。(想定通り)
$ curl -X POST -H "Content-Type: application/json" \
-d '{"Name":"Hello株式会社"}' \
https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/employees
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot POST /employees</pre>
</body>
</html>
おわりに
Serverless Express + AWS Lambda + API Gateway の構成を AWS CDK でデプロイして作成してみました。
どなたかの参考になれば幸いです。
参考
以上