AWS CDK + Lambda + API Gateway で REST APIを作成する
AWS CDK + Lambda + API Gateway で REST API を作成する方法について解説する。
AWS CDKとは?
インフラをコードで管理できる仕組みを Infrastructure as Code(IaC) という。Terraformなどが有名で、 AWS CDK (AWS Cloud Development Kit) も、IaCを実現するためのツールのひとつ。
AWS CDKの利点
- プログラミング言語で記述できる(TypeScriptかPython使っている人がほとんどっぽい)。今回はTypeScriptで作成。
- Terraformより簡単らしい。
AWS CDKの欠点
- AWSでしか使えない。TerraformはAzureでもGCPでも使える。
事前準備
- AWSアカウントを作成する
- aws configureの設定
- node18系をインストール
- 下記のように表示されればOK
$ node -v v18.15.0 $ npx aws-cdk@2 --version 2.84.0 (build f7c792f)
AWS CDKの初期プロジェクトを作成
$ pwd
/<任意の作業ディレクトリ>
$ mkdir aws-cdk-test
$ cd aws-cdk-test
$ npx aws-cdk@2 init app --language typescript
新規プロジェクトが作成され、下記のようなディレクトリ構成となる
$ tree -I node_modules --dirsfirst
.
├── bin
│ └── aws-cdk-test.ts
├── lib
│ └── aws-cdk-test-stack.ts
├── test
│ └── aws-cdk-test.test.ts
├── README.md
├── cdk.json
├── jest.config.js
├── package-lock.json
├── package.json
└── tsconfig.json
lib/aws-cdk-test-stack.ts
があり、Stackクラスを継承したクラスが実装されている。このスタックを単位にリソースをデプロイすることになる。
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
// import * as sqs from 'aws-cdk-lib/aws-sqs';
export class AwsCdkTestStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// The code that defines your stack goes here
// example resource
// const queue = new sqs.Queue(this, 'AwsCdkTestQueue', {
// visibilityTimeout: cdk.Duration.seconds(300)
// });
}
}
esbuildをインストール
デプロイなどをするときに必要となる。esbuildをインストールしていなければ、Dockerを使ってデプロイなどを実行する。従って、Dockerで構わないという場合はインストール不要。
$ npm install --save-dev esbuild@0
AWS Lambda関数とAPI Gatewayを作成
ここがメインパート。
まず、lib/hello-world.ts
ファイルを作成する。{ message: "Hello World!" }
とレスポンスを返すhandler関数を定義する。Lambdaでは特定のイベント(今回はAPI GatewayのAPIをコールすること)が発生すると、事前に設定したhandler関数が自動的に呼び出される。
export const handler = async () => {
const responseBody = { message: "Hello World!" };
const response = {
statusCode: 200,
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(responseBody),
};
return response;
}
lib/aws-cdk-test-stack.ts
を編集して、下記のように上書きする。
import * as cdk from 'aws-cdk-lib';
import { Runtime } from "aws-cdk-lib/aws-lambda";
import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs";
import { Construct } from 'constructs';
export class AwsCdkTestStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Lambda
const nameHelloWorldFunc = "helloWorldFunc"
const helloWorldFunc = new NodejsFunction(this, nameHelloWorldFunc, {
// Lambdaが呼び出すべき関数(ハンドラ)が含まれているファイルを指定している
entry: "lib/hello-world.ts",
runtime: Runtime.NODEJS_18_X,
functionName: nameHelloWorldFunc,
});
// API Gateway (REST API)
const restApi = new cdk.aws_apigateway.RestApi(this, "nameRestApi", {
deployOptions: {
stageName: 'v1',
},
restApiName: `Rest_API_with_Lambda`,
});
// API Gatewayにリクエスト先のリソースを追加(エンドポイントの定義)
const restApiHelloWorld = restApi.root.addResource('hello_world');
// API GatewayのリソースにLambda関数を紐付け
restApiHelloWorld.addMethod("GET", new cdk.aws_apigateway.LambdaIntegration(helloWorldFunc));
}
}
Lambda関数とAPI Gatewayを作成するためのコードの編集は以上。
デプロイ
最後にAWSにデプロイをする。
$ npm run cdk deploy
省略…
Do you wish to deploy these changes (y/n)? # y で進める
aws configureの設定で指定した環境にデプロイされて、 https://xxxxxxxxxx.execute-api.xxxxxxxxxx.amazonaws.com/v1/
のようなURLが表示される。 lib/aws-cdk-test-stack.ts
の const restApiHelloWorld = restApi.root.addResource('hello_world');
の箇所で、 hello_world
をエンドポイントとして定義している。
従って、 https://xxxxxxxxxx.execute-api.xxxxxxxxxx.amazonaws.com/v1/hello_world
にアクセスして、下記のようなレスポンスが返ってくれば完成。
{
"message": "Hello World!"
}
参考
Discussion