LoginSignup
1
1

More than 1 year has passed since last update.

【CDK】 色んな言語でCRUD API作る【Go】

Posted at

この記事について

AWS CDKv2でCRUD操作ができるAPIを作る
今回はGoを使う

プロジェクト初期化

CLIのインストール

CLI自体はnodeのものを使う(ので導入済みならスキップ)

npm install -g aws-cdk
cdk --version

バージョンが表示されればOK

CDK Toolkitのデプロイ

初回のみCDKを利用する際に必要となるファイル群のデプロイが必要
→これもやったことがあるならスキップ

cdk bootstrap aws://${ACCOUNT}/${REGION}

以下のように表示されればOK

✅  Environment aws://${ACCOUNT}/${REGION} bootstrapped.

※異なるアカウント、リージョンでCDKを利用する場合はまたこの作業が必要になる

プロジェクト初期化

適当なディレクトリで↓を実行

cdk init app --language go

モジュールのインストール

必要なモジュールをgo.modに書き込む

go.mod
module todoapp-go

go 1.16

require (
	github.com/aws/aws-cdk-go/awscdk/v2 v2.34.2
	github.com/aws/aws-cdk-go/awscdklambdagoalpha/v2 v2.34.2-alpha.0
	github.com/aws/aws-lambda-go v1.34.0
	github.com/aws/aws-sdk-go-v2 v1.16.7
	github.com/aws/aws-sdk-go-v2/config v1.15.14
	github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.9.7
	github.com/aws/aws-sdk-go-v2/service/dynamodb v1.15.9
	github.com/aws/constructs-go/constructs/v10 v10.1.58
	github.com/aws/jsii-runtime-go v1.63.0
	github.com/google/uuid v1.3.0
)

書いたら↓を実行してgo.sumが作成されたら完了

go mod tidy

実装

CDKのコードを書く

todoapp-go.go
package main

import (
	"fmt"

	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/aws-cdk-go/awscdk/v2/awsapigateway"
	"github.com/aws/aws-cdk-go/awscdk/v2/awsdynamodb"
	"github.com/aws/aws-cdk-go/awscdk/v2/awsiam"
	"github.com/aws/aws-cdk-go/awscdk/v2/awslogs"
	"github.com/aws/aws-cdk-go/awscdklambdagoalpha/v2"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type TodoappGoStackProps struct {
	awscdk.StackProps
}

func NewTodoappGoStack(scope constructs.Construct, id string, props *TodoappGoStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// DynamoDB
	table := awsdynamodb.NewTable(stack, jsii.String("TodosTable"), &awsdynamodb.TableProps{
		TableName: jsii.String("todoapp-go-todos-table"),
		PartitionKey: &awsdynamodb.Attribute{
			Name: jsii.String("id"),
			Type: awsdynamodb.AttributeType_STRING,
		},
		RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
	})

	// Lambda関数
	function := awscdklambdagoalpha.NewGoFunction(stack, jsii.String("TodoFunction"), &awscdklambdagoalpha.GoFunctionProps{
		FunctionName: jsii.String("todoapp-go-function"),
		Entry:        jsii.String("src"),
		Environment: &map[string]*string{
			"TODOS_TABLE_NAME": table.TableName(),
		},
	})
	// LambdaにDynamoDBのCRUD操作権限を付与
	function.AddToRolePolicy(awsiam.NewPolicyStatement(&awsiam.PolicyStatementProps{
		Effect: awsiam.Effect_ALLOW,
		Actions: jsii.Strings(
			"dynamodb:Scan",
			"dynamodb:PutItem",
			"dynamodb:UpdateItem",
			"dynamodb:DeleteItem"),
		Resources: jsii.Strings(*table.TableArn()),
	}))

	// LogGroup
	awslogs.NewLogGroup(stack, jsii.String("TodoFunctionLogs"), &awslogs.LogGroupProps{
		LogGroupName:  jsii.String(fmt.Sprintf("/aws/lambda/%s", *function.FunctionName())),
		RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
	})

	// API Gateway
	restapi := awsapigateway.NewRestApi(stack, jsii.String("TodoApi"), &awsapigateway.RestApiProps{
		RestApiName: jsii.String("todoapp-go-api"),
		DefaultCorsPreflightOptions: &awsapigateway.CorsOptions{
			AllowOrigins: awsapigateway.Cors_ALL_ORIGINS(),
			AllowMethods: awsapigateway.Cors_ALL_METHODS(),
			AllowHeaders: awsapigateway.Cors_DEFAULT_HEADERS(),
			StatusCode:   jsii.Number(200),
		},
	})
	todosResource := restapi.
		Root().
		AddResource(jsii.String("todos"), nil)
	todosResource.AddMethod(jsii.String("GET"), awsapigateway.NewLambdaIntegration(function, nil), nil)
	todosResource.AddMethod(jsii.String("POST"), awsapigateway.NewLambdaIntegration(function, nil), nil)
	todoIdResource := todosResource.AddResource(jsii.String("{id}"), nil)
	todoIdResource.AddMethod(jsii.String("PUT"), awsapigateway.NewLambdaIntegration(function, nil), nil)
	todoIdResource.AddMethod(jsii.String("DELETE"), awsapigateway.NewLambdaIntegration(function, nil), nil)

	return stack
}

func main() {
	app := awscdk.NewApp(nil)

	NewTodoappGoStack(app, "TodoappGoStack", &TodoappGoStackProps{
		awscdk.StackProps{
			Env: env(),
		},
	})

	app.Synth(nil)
}

func env() *awscdk.Environment {
	return nil
}

例によって例のごとく今回もLambdaはGo言語専用のモジュールawscdklambdagoalphaを使っている
こちらについて少し補足↓

awscdklambdagoalphaについて

function := awscdklambdagoalpha.NewGoFunction(stack, jsii.String("TodoFunction"), &awscdklambdagoalpha.GoFunctionProps{
	FunctionName: jsii.String("todoapp-go-function"),
	Entry:        jsii.String("src"),
	Environment: &map[string]*string{
		"TODOS_TABLE_NAME": table.TableName(),
	},
})

EntryにLambdaのコードを置いてあるディレクトリを指定すればOK
また、エントリーポイントとなるファイルの名前はmain.goでなければならない点に注意

todoapp-go
 ├-go.mod
 ├-go.sum
 ├-todoapp-go.go
 └-src
   └-main.go ←Lambdaのエントリーポイント

Lambdaのコード実装

こちらのサンプルコードを参照
Goはほぼ使った経験がないのであまり参考にならないかもしれない(特にメソッドやパスに応じたルーティングとか)

デプロイ

↓を実行

cdk deploy TodoappGoStack

動作確認

↓を実行

export ENDPOINT="API Gatewayのエンドポイント"
bash tests/test.bash

参考リンク

サンプルコード
https://github.com/tetsu0000/todoapp-go

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1