概要
前回はLambda Layerを導入した。
今回はAPI Gatewayを使ってHTTPでLambda Functionsを叩けるようにする。
やること
- ローカル実行
- POSTのテスト
- GETでパラメータを取得できることのテスト
やらないこと
デプロイ
コード
GET用のFunctionsの追加
src/lambda/handlers/get-echo.ts
import { APIGatewayProxyHandler } from 'aws-lambda';
import * as response from '../utilities/reponse';
export const echoHandler: APIGatewayProxyHandler = async (event) => {
const { httpMethod, path, pathParameters } = event;
if (httpMethod !== 'GET') {
throw new Error(`getMethod only accept GET method, you tried: ${httpMethod}`);
}
console.log('received:', JSON.stringify(event));
// Get id from pathParameters from APIGateway because of `/{id}` at template.yml
const params = pathParameters;
if (!params || !params.id) {
return response.badRequest('parameter is required')
}
const { id } = params;
const res = response.ok(id);
console.log(`response from: ${path} statusCode: ${res.statusCode} body: ${res.body}`);
return res;
};
Stack
lib/sample-stack.ts
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import { NodejsFunction } from '@aws-cdk/aws-lambda-nodejs';
+ import * as apigateway from '@aws-cdk/aws-apigateway'
import { NODE_LAMBDA_LAYER_DIR } from './process/setup';
export class SampleStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
- new NodejsFunction(this, 'hello', {
+ const helloFunction = new NodejsFunction(this, 'hello', {
runtime: lambda.Runtime.NODEJS_14_X,
entry: 'src/lambda/handlers/hello.ts',
functionName: 'kotahello',
handler: 'lambdaHandler'
});
const nodeModulesLayer = new lambda.LayerVersion(this, 'NodeModulesLayer',
{
code: lambda.AssetCode.fromAsset(NODE_LAMBDA_LAYER_DIR),
compatibleRuntimes: [lambda.Runtime.NODEJS_14_X]
}
);
new NodejsFunction(this, 'test', {
runtime: lambda.Runtime.NODEJS_14_X,
entry: 'src/lambda/handlers/test.ts',
functionName: 'kotatest',
bundling: {
externalModules: [
'aws-sdk', // Use the 'aws-sdk' available in the Lambda runtime
'date-fns', // Layrerに入れておきたいモジュール
],
define: { // Replace strings during build time
'process.env.API_KEY': JSON.stringify(`\\"${'xxx-xxx'}\\"`), // バグってそう.エスケープしないとInvalid define valueのエラー
},
},
layers: [nodeModulesLayer],
});
+ const echoFunction = new NodejsFunction(this, 'echo', {
+ runtime: lambda.Runtime.NODEJS_14_X,
+ entry: 'src/lambda/handlers/get-echo.ts',
+ functionName: 'get-echo',
+ handler: 'echoHandler'
+ });
+ const api = new apigateway.RestApi(this, 'ServerlessRestApi', { cloudWatchRole: false });
+ api.root.addMethod('POST', new apigateway.LambdaIntegration(helloFunction));
+ api.root.addResource('{id}').addMethod('GET', new apigateway.LambdaIntegration(echoFunction));
}
}
package.json
package.json
{
"name": "myapp",
"version": "0.1.0",
"scripts": {
"build": "tsc",
"watch": "tsc -w",
"test": "jest",
"cdk": "cdk",
"bundle": "cdk synth && cdk synth > cdk.out/template.yaml",
"localinvoke": "cd cdk.out && sam.cmd local invoke testAF53AC38 --no-event",
+ "dev-server": "cd cdk.out && sam.cmd local start-api"
},
"devDependencies": {
"@aws-cdk/assert": "^1.93.0",
+ "@aws-cdk/aws-apigateway": "^1.93.0",
"@aws-cdk/aws-lambda-nodejs": "^1.93.0",
"@aws-cdk/core": "^1.93.0",
"@types/aws-lambda": "^8.10.72",
"@types/fs-extra": "^9.0.8",
"@types/jest": "^26.0.10",
"@types/node": "10.17.27",
"aws-cdk": "^1.93.0",
"esbuild": "^0.9.0",
"fs-extra": "^9.1.0",
"jest": "^26.4.2",
"source-map-support": "^0.5.19",
"ts-jest": "^26.2.0",
"ts-node": "^9.0.0",
"typescript": "~3.9.7"
},
"dependencies": {
"date-fns": "^2.19.0"
}
}
結果
npm run dev-server
- getもpostも想定通りの結果を返してくれた
参考
AWS CDKでAPI Gateway+Lambdaを作成する際のベストなスタック構成について
API Gatewayのローカルでの実行
サーバーレスをこれから始める方へ!「形で考えるサーバーレス設計」のCDKテンプレート(web/mBaaS編)を試して解説してみた
AWS CDKでTypeScriptで書かれたLambdaにLambda ProxyなREST APIを追加する
@aws-cdk/aws-apigateway module