CDK で API Gateway + Lambda (Go)
API Gateway + Lambda (Go) の構成を CDK でデプロイする。
作るもの
{"name":"test"}
というリクエストボディを POST すると
Hello test!
というレスポンスが返ってくる API を作る。
ディレクトリ構成
少し複雑なソースコードを想定したかったので、Go のソースコードは分割してみた。
test-lambda-go
|
|-cdk
| |-(このディレクトリ内で cdk init する)
|
|-lambda
|-go.mod
|-go.sum
|-cmd
| |-hello
| |-main.go
|-internal
|-handler
|-handler.go
Go のソースコード
go mod init gitlab.com/k1350/test-lambda-go
で初期化したとする。
lambda/cmd/hello/main.go
package main
import (
"github.com/aws/aws-lambda-go/lambda"
"gitlab.com/k1350/test-lambda-go/internal/handler"
)
func main() {
lambda.Start(handler.HandleRequest)
}
lambda/internal/handler/handler.go
package handler
import (
"context"
"encoding/json"
"fmt"
"github.com/aws/aws-lambda-go/events"
)
type Input struct {
Name string `json:"name"`
}
func HandleRequest(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
input, err := parse(request.Body)
if err != nil {
return events.APIGatewayProxyResponse{
Body: err.Error(),
StatusCode: 500,
}, err
}
return events.APIGatewayProxyResponse{
StatusCode: 200,
Body: fmt.Sprintf("Hello %s!", input.Name),
}, nil
}
func parse(inputs string) (*Input, error) {
var req Input
err := json.Unmarshal([]byte(inputs), &req)
if err != nil {
return nil, err
}
return &req, nil
}
少なくとも Body と StatusCode を持つ構造体で返さないと API Gateway 側でレスポンスをパースできずにエラーになる。
CDK のコード
cdk init --language typescript
で初期化したとする。
cdk/package.json
cdk init で入った aws-cdk
のバージョンと、Go のために入れなければならない @aws-cdk/aws-lambda-go-alpha
の依存バージョンが合わないエラーが出たので最終的な package.json を記載する。
{
"name": "cdk",
"version": "0.1.0",
"bin": {
"cdk": "bin/cdk.js"
},
"scripts": {
"build": "tsc",
"watch": "tsc -w",
"test": "jest",
"cdk": "cdk"
},
"devDependencies": {
"@types/jest": "^29.2.2",
"@types/node": "18.11.9",
"@types/prettier": "2.7.1",
"aws-cdk": "2.50.0",
"jest": "^29.2.2",
"ts-jest": "^29.0.3",
"ts-node": "^10.9.1",
"typescript": "~4.8.4"
},
"dependencies": {
"@aws-cdk/aws-lambda-go-alpha": "^2.50.0-alpha.0",
"aws-cdk-lib": "2.50.0",
"constructs": "^10.0.0",
"source-map-support": "^0.5.21"
}
}
cdk/lib/cdk-stack.ts
import { Stack, StackProps, aws_apigateway } from "aws-cdk-lib";
import { Construct } from "constructs";
import { GoFunction } from "@aws-cdk/aws-lambda-go-alpha";
export class CdkStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const lambda = new GoFunction(this, "handler", {
entry: "../lambda/cmd/hello",
});
const api = new aws_apigateway.RestApi(this, "sampleApiGateway");
const sample = api.root.addResource("sample");
const integration = new aws_apigateway.LambdaIntegration(lambda);
sample.addMethod("POST", integration);
}
}
デプロイと後片付け
cdk deploy
すると API が作成される。
cdk destroy
で諸々削除されるが、Lambda に zip アップロードするために S3 にファイルを一時置きしており、そのファイルは削除されなかった。
自動で削除する方法は調べたが今のところ不明。とりあえずデプロイ終わったら自分で削除する。
以上