AWS SDK for Go V2 をちょっとだけ触ってみた

AWS SDK for Go V2 が正式版となったので、ちょっとだけ触ってみました

aws.github.io

Pagination の変更

V1 から V2 に移行するにあたって、コードを書く上で最も影響がありそうな変更が、リスト系の API で使用する Pagination の変更です。

V1 では、個々のページの処理はコールバック関数で行う形でした。

   input := &s3.ListObjectsV2Input{Bucket: aws.String("test-bucket.go-aws-sdk.sample")}
    err := s3Client.ListObjectsV2Pages(input, func(output *s3.ListObjectsV2Output, lastPage bool) bool {
        for _, content := range output.Contents {
            fmt.Println(*content.Key)
        }
        return true
    })
    if err != nil {
        fmt.Printf("%v\n", err)
        panic(err)
    }

V2 ではイテレータを返す形になっていて、単純に同じコンテキストの中で for ループで回すことができます。

   input := &s3.ListObjectsV2Input{Bucket: aws.String("test-bucket.go-aws-sdk.sample")}
    paginator := s3.NewListObjectsV2Paginator(s3Client, input)

    for paginator.HasMorePages() {
        output, err := paginator.NextPage(ctx)
        if err != nil {
            fmt.Printf("%v\n", err)
            panic(err)
        }
        for _, content := range output.Contents {
            fmt.Println(*content.Key)
        }
    }

V1 だとコールバック関数内のエラーを外に引き回したりするのが面倒だったので、シンプルになるのは嬉しい変更ですが、これまでの Pagination 系関数をバッサリ消してしまったのは見切りが良すぎるというか…

モジュール化

V1 では github.com/aws/aws-sdk-go という一塊のモジュールになっていましたが、 V2 ではサービス API ごとに分割されていますね。ビルド後のバイナリサイズも相応に小さくなるようです。

上記の2つのサンプルコードを (最低限動作する形にして) それぞれ go build -ldflags="-s -w" でビルドしたところ、バイナリのサイズは 8,216,5766,545,408 と 1.7MB ほどの削減となりました。

ほか

Waiter 系は、非同期で実行される API の処理が完了するまで、状況を ポーリングしつつスレッドをブロックしてくれる機能ですね。例えば ECS のタスクが起動するまで待ってくれる TaskRunningWaiter などは、デプロイツールのようなものを作るのに便利そうです。

気になったところ

Paginator もそうですが、 session や config の呼び出し周り、あるいは DynamoDB の AttributeValue 系が別モジュールに移動しているなど、破壊的な変更が結構あるので、単純な移行は結構難しそうです。わざわざモジュール名を変えているのでしばらくは併存させるのでしょうが、いつ公開が止まるかわからんので、既存の資産をいつ、どうやって移行していくべきかが悩みどころですね…