API Gatewayと組み合わせて利用するLambda関数を作成します。
環境
% sw_vers
ProductName: macOS
ProductVersion: 14.7.3
BuildVersion: 23H417
% aws --version
aws-cli/2.24.25 Python/3.12.9 Darwin/23.6.0 exe/x86_64
% cdk --version
2.1004.0 (build f0ad96e)
% npm --version
11.1.0
% node --version
v20.17.0
Lambda関数を構築
import * as cdk from 'aws-cdk-lib';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as lambda_nodejs from 'aws-cdk-lib/aws-lambda-nodejs';
import { Construct } from 'constructs';
export interface SampleApiResourceProps {
product: string;
environment: string;
restApi: apigateway.RestApi;
}
export class SampleApiResource extends Construct {
constructor(scope: Construct, id: string, props: SampleApiResourceProps) {
super(scope, id);
const product = props.product;
const env = props.environment;
const sampleApiResource = props.restApi.root.addResource('sample');
const getSampleFunctionId: string = `${product}-${env}-get-sample`;
const getSampleFunction = new lambda_nodejs.NodejsFunction(
this,
getSampleFunctionId,
{
entry: '../lambda/api/sample.ts',
handler: 'handler',
runtime: lambda.Runtime.NODEJS_22_X,
memorySize: 512,
timeout: cdk.Duration.seconds(10),
bundling: {
target: 'es2022',
minify: true,
},
},
);
sampleApiResource.addMethod(
'GET',
new apigateway.LambdaIntegration(getSampleFunction)
);
}
}
aws-cdk-lib/aws-apigateway/RestApi
を外部で作成し、Props経由で受け取る想定です。
発展
ソフトウェア開発で「Lambda関数が1つだけ」という場面は少ないと思います。
aws-cdk-lib/aws-lambda-nodejs/NodejsFunction
のPropsには、entry
、handler
、runtime
、etc...と、様々の設定項目があり、それらを、Lambda関数毎に書くのは大変です。
Node.js
をまとめてバージョンアップしたい時に、何十ヶ所も変えていくのも手間になりそうです。
そこで、ラッパー関数的なものを作成することにしました。
作成した関数
import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as lambda_nodejs from 'aws-cdk-lib/aws-lambda-nodejs';
import type { Construct } from 'constructs';
// Properties default value: interface NodejsFunctionProps
const DEFAULT_HANDLER: string = 'handler';
const DEFAULT_RUNTIME: lambda.Runtime = lambda.Runtime.NODEJS_22_X;
const DEFAULT_MEMORY_SIZE: number = 512; // MB
const DEFAULT_TIMEOUT: cdk.Duration = cdk.Duration.seconds(10);
// Properties default value: interface BundlingOptions
const DEFAULT_TARGET: string = 'es2022';
const DEFAULT_MINIFY: boolean = true;
export interface LambdaNodejsFunctionProps {
entry: string;
handler?: string;
runtime?: lambda.Runtime;
memorySize?: number;
timeout?: cdk.Duration;
}
export function buildLambdaNodejsFunction(
scope: Construct,
id: string,
props: LambdaNodejsFunctionProps,
): lambda_nodejs.NodejsFunction {
const nodejsFunctionProps: lambda_nodejs.NodejsFunctionProps = {
entry: props.entry,
handler: props.handler ?? DEFAULT_HANDLER,
runtime: props.runtime ?? DEFAULT_RUNTIME,
memorySize: props.memorySize ?? DEFAULT_MEMORY_SIZE,
timeout: props.timeout ?? DEFAULT_TIMEOUT,
bundling: {
target: DEFAULT_TARGET,
minify: DEFAULT_MINIFY,
},
};
return new lambda_nodejs.NodejsFunction(scope, id, nodejsFunctionProps);
}
new NodejsFunction(...)
の代わりにbuildLambdaNodejsFunction(...)
として利用します。
Props
で、entry
のみを必須にして、他を任意にしました。任意の部分は、指定されなければデフォルト値が指定されます。
この関数を利用すると、最初のソースコードは次のようになります。
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import { Construct } from 'constructs';
import { buildLambdaNodejsFunction } from '../lambdaNodejsFunction';
export interface SampleApiResourceProps {
product: string;
environment: string;
restApi: apigateway.RestApi;
}
export class SampleApiResource extends Construct {
constructor(scope: Construct, id: string, props: SampleApiResourceProps) {
super(scope, id);
const product = props.product;
const env = props.environment;
const sampleApiResource = props.restApi.root.addResource('sample');
const getSampleFunctionId: string = `${product}-${env}-get-sample`;
const getSampleFunction = buildLambdaNodejsFunction(
this,
getSampleFunctionId,
{
entry: '../lambda/api/sample.ts',
},
);
sampleApiResource.addMethod(
'GET',
new apigateway.LambdaIntegration(getSampleFunction),
);
}
}
ソースコードがスッキリしました。
スペックがデフォルト値で問題ないのであれば、Lamdba関数自体のソースコードへのパスだけを意識してコーディングできるのは相当楽です。
Next
作成したLambda関数を API Gateway と組み合わせてアクセスできるようにします。