APIGateaway + LambdaをCDKで作成
cdkにてAPIGateway + Lambdaの作成方法についてのまとめ
ServerlessFWがV4から有料になったのでcdkで構築する
typescriptを用いて構築します。
aws cdkはインストール済みとします
プロジェクトの初期化
新しいCDKプロジェクトの初期化
mkdir my-api-lambda
cd my-api-lambda
cdk init app --language typescript
cdk init app --language typescript
を実行するとTypeScript用のプロジェクトが作成されます。
下記が作成された中身の例です
my-api-lambda/
├── bin/
│ └── my-api-lambda.ts
├── lib/
│ └── my-api-lambda-stack.ts
├── test/
│ └── my-api-lambda.test.ts
├── 省略
-
bin
: エントリーポイントとなる実行ファイルを格納-
my-api-lambda.ts
: 実際に実行するlambdaファイル - 複数lambdaを作成する場合こちらに新規でディレクトリ・ファイルの追加することも可能
-
-
lib
: CDKスタックの定義ファイルを格納-
my-api-lambda-stack.ts
: インフラストラクチャを定義する主要なスタックファイル - LambdaやAPIGatewayの設定を記述
-
Lambdaの作成
bin/my-api-lambda.tsの中に実際の処理を作成していきます。
複数のlambdaを作成する場合、ディレクトリを作成してその中にlambda実行ファイルを作成することも可能です。
1番簡単な例として、APIがリクエストされたら「Hello World」を返すLambdaです。
// bin/my-api-lambda.ts
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
export async function handler(event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> {
return {
statusCode: 200,
body: JSON.stringify({ message: "Hello World!" }),
};
}
aws-lambda
の部分は下記でインストールできます。
npm install --save-dev @types/aws-lambda
クエリパラメータ
APIのリクエストでクエリパラメータを使用する場合
下記の方法で取得できます。
const queryParams = event.queryStringParameters
例
URL: https://api.example.com/resource?name=John&age=30
結果: { name: 'John', age: '30' }
パスパラメータ
パスパラメータを使用して値を受け取る場合
const pathParams = event.pathParameters;
例
/users/{userId}
の場合
URL: https://api.example.com/users/123
結果: { userId: '123' }
リクエストボディの取得
POSTでリクエストボディを受け取る場合
const requestBody = event.body ? JSON.parse(event.body) : null;
例
リクエストボディ: { "title": "例", "content": "ポストの例" }
結果
{
"title": "例",
"content": "ポストの例"
}
スタックの作成
lib/my-api-lambda-stack.ts
にあるファイルを修正して、先程作成したLambdaと呼び出すためのAPIGatewayを定義していきます。
@aws-cdk/aws-lambda-nodejs
を使用することでTypeScriptコードを自動的にバンドル・コンパイルしてくれます。
npm install @aws-cdk/aws-lambda-nodejs esbuild
Lambdaの作成
const myLambda = new lambdaNodejs.NodejsFunction(this, 'MyLambdaHandler', {
runtime: lambda.Runtime.NODEJS_20_X,
entry: 'bin/my-api-lambda.ts',
handler: 'handler',
environment: {
MY_VARIABLE: '123',
}
});
new lambdaNodejs.NodejsFunction
: Lambdaの作成をおこなう
runtime
: Lambda関数の実行環境を指定
entry
: TypeScriptのエントリーポイント
handler
: エクスポートされた関数名
environment
: 環境変数の設定
Lambdaが複数ある場合は1つずつ作成する必要があります。
entryだけ異なる場合は関数化してファイルパスを引数で渡すだけで作成できるようにすると便利です。
APIGatewayの作成
const api = new apigateway.RestApi(this, 'MyApi', {
restApiName: 'My Service',
description: 'This is my API service.',
});
new apigateway.RestApi
: Apiの作成
restApiName
: API名
エンドポイントとメソッドの追加
/users
でアクセスしたい場合
// apiに追加
const users = api.root.addResource('users');
GET
でリクエストする場合
users.addMethod('GET');
/users/{userId}
でパスパラメータの追加
// usersにaddResourceで追加
const user = users.addResource('{userId}');
user.addMethod('POST')
独自ドメインの追加
APIGatewatに独自ドメインを追加する場合
証明書のArnを取得して設定をおこなう
// 証明書の取得
const certificateArn = '証明書のarnを設定';
const certificate = certificatemanager.Certificate.fromCertificateArn(this, 'Certificate', certificateArn);
// 独自ドメインの追加
api.addDomainName('CustomDomain', {
domainName: 'api.example.com',
certificate: certificate,
});
ステージの設定
デフォルトのステージは/prodですが変更することが可能
const api = new apigateway.RestApi(this, 'MyApi', {
restApiName: 'My Service',
description: 'This is my API service.',
deployOptions: {
stageName: 'dev'
}
});
deployOptions
のstageName
に設定することで/prodeではなく、/devに変更可能
実際のStack
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
mport * as lambdaNodejs from 'aws-cdk-lib/aws-lambda-nodejs';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
export class MyApiLambdaStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Lambda関数を作成
const myLambda = new lambdaNodejs.NodejsFunction(this, 'MyLambdaHandler', {
runtime: lambda.Runtime.NODEJS_20_X,
entry: 'bin/my-api-lambda.ts',
handler: 'handler.handler',
});
// API Gatewayを作成
const api = new apigateway.RestApi(this, 'MyApi');
// リソースとメソッドを設定
const users = api.root.addResource('users');
const user = users.addResource('{userId}');
user.addMethod('GET', new apigateway.LambdaIntegration(myLambda));
user.addMethod('POST', new apigateway.LambdaIntegration(myLambda));
}
}
その他
APIGateway+Lambdaをcdkで作成する方法です。
実際は特定のVPC内に設置や、特定のアカウントからのみアクセス可能などセキュリティ周りの設定が追加になるかもです。
Discussion