michimani.net

AWS SDK for Go v2 の RC 版が公開されたのでとりあえず触ってみる

2020-12-26

AWS SDK for Go の RC 版が公開されたので、CloudWatch Logs と DynamoDB について、以前に v1 で操作したときとどのように変わったのか確認してみます。

※ 2020/12/26 時点での情報です
※ RC 版ということなので正式版になるまでに変更が加えられる可能性があります

目次

v1 で触ってみた記事はこちら。

概要

AWS SDK for Go v2 の RC 版が公開されました。

AWS SDK for Go version 2 (v2) – Release Candidate | AWS Developer Blog

Developer Preview が公開されたのは 2017/12/21 みたいなので、約 3 年の間に熟された結果の RC 版です。

AWS SDK for Go 2.0 Developer Preview | AWS Developer Blog

使ってみる

AWS Developer Blog に従って準備していきます。

$ mkdir go-sdk-v2-rc-demo
$ cd go-sdk-v2-rc-demo
$ go mod init go-sdk-v2-rc-demo

今回は CloudWatch Logs と DynamoDB をさわるので、それぞれのディレクトリも作っておきます。

$ mkdir -p cwlogs dynamodb
$ tree
.
├── cwlogs
├── dynamodb
└── go.mod

2 directories, 1 file

AWS SDK for Go v2 のドキュメントはこちらです。

sdk · pkg.go.dev

v2 を利用する場合、 import 文は下記のようになります。

import (
	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs"
	"github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs/types"
)

今回は CloudWatch Logs と DynamoDB について実装しますが、ここではその一部分のみについて書いています。その他の実装部分についてはこのリポジトリを見てください。

CloudWatch Logs

前回と同じように、ロググループの作成からストリームの作成、ログイベントの Put までやってみます。

まずクライアントを生成するところから違ってます。

config, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
	log.Fatalln(err)
}
client := cloudwatchlogs.NewFromConfig(config)

あとは、各サービスの関数実行時に、第一引数に context.Context を渡すようになってます。例えば、ロググループを作成する部分だと下記のような感じ。

in := cloudwatchlogs.CreateLogGroupInput{
	LogGroupName: aws.String(name),
}

_, cerr := client.CreateLogGroup(context.TODO(), &in)
if cerr != nil {
	return cerr
}

DynamoDB

テーブルの作成、項目の追加、普通のスキャン、特定の属性のみ取得するスキャンを試します。

v1 からの違いとして、定数に当たるものは別のパッケージとして分割されています。例えば、テーブルを作成するときの実装は下記のようになります。

func createTable(client *dynamodb.Client, name string) error {
	describeIn := dynamodb.DescribeTableInput{
		TableName: aws.String(name),
	}
	_, err := client.DescribeTable(context.TODO(), &describeIn)
	if err == nil {
		// table exists
		return nil
	}

	in := dynamodb.CreateTableInput{
		TableName: aws.String(name),
		KeySchema: []types.KeySchemaElement{
			{
				AttributeName: aws.String("Name"),
				KeyType:       types.KeyTypeHash,
			},
			{
				AttributeName: aws.String("CreatedAt"),
				KeyType:       types.KeyTypeRange,
			},
		},
		AttributeDefinitions: []types.AttributeDefinition{
			{
				AttributeName: aws.String("Name"),
				AttributeType: types.ScalarAttributeTypeS,
			},
			{
				AttributeName: aws.String("CreatedAt"),
				AttributeType: types.ScalarAttributeTypeN,
			},
		},
		BillingMode: types.BillingModePayPerRequest,
	}

	if _, err := client.CreateTable(context.TODO(), &in); err != nil {
		return err
	}

	return nil
}

dynamodb.CreateTableInputKeySchema フィールドは、 v1 では []*KeySchemaElement だったものが v2 では []types.KeySchemaElement という感じで別パッケージ types 1 の型を使うようになっています。
また、 KeySchema 内で指定する各属性の KeyTypetypes パッケージの KeyTypeHash などを使用するようになっています。(CloudWatch Logs でもその様になっている部分がありました)

あとは、 Go の型と DynamoDB の Attribute との変換については、 attributevalue.MarshalMap を使って下記のように書けます。

type SmapleItem struct {
	Name      string `json:"name"`
	CreatedAt int64  `json:"created_at"`
	Message1  string `json:"message1"`
	Message2  string `json:"message2"`
	Message3  string `json:"message3"`
}

item := SmapleItem{
	Name:      fmt.Sprintf("Sample Item %d", n),
	CreatedAt: time.Now().UnixNano(),
	Message1:  fmt.Sprintf("This is a sample message %d-1", n),
	Message2:  fmt.Sprintf("This is a sample message %d-2", n),
	Message3:  fmt.Sprintf("This is a sample message %d-3", n),
}
if err := putItem(client, tableName, item); err != nil {
	log.Fatal(err)
}

func putItem(client *dynamodb.Client, tableName string, item SmapleItem) error {
	av, err := attributevalue.MarshalMap(item)
	if err != nil {
		return err
	}

	in := dynamodb.PutItemInput{
		TableName: aws.String(tableName),
		Item:      av,
	}
	_, perr := client.PutItem(context.TODO(), &in)
	if perr != nil {
		return err
	}

	fmt.Println(item.Name)

	return nil
}

めっちゃ便利!と思ったんですが、これ v1 でもあったみたいですね。やりながら気づきました。

まとめ

AWS SDK for Go v2 の RC 版が公開されたので触ってみた話でした。
今回はざっくりサンプル実装してみた感じなので、 v1 とどの辺が変わったかはもう少し時間を書けて見てみたいと思います。

※ 2020/12/26 時点での情報です
※ RC 版ということなので正式版になるまでに変更が加えられる可能性があります


  1. types · pkg.go.dev  ↩︎


comments powered by Disqus