😸
GoでLocalStackのS3を操作する
はじめに
前回の記事では、GoからLocalStackを扱う方法を紹介しました。
今回は、その中で紹介したLocalStack上のS3を操作するソースコードについて解説します。
コードの解説
ソースコード再掲
以下に、前回の記事で紹介したGoのコードを再掲します。
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
func main() {
// ダミー用の認証情報
os.Setenv("AWS_ACCESS_KEY_ID", "test")
os.Setenv("AWS_SECRET_ACCESS_KEY", "test")
cfg, err := config.LoadDefaultConfig(context.TODO(),
config.WithRegion("us-east-1"),
)
if err != nil {
log.Fatalf("failed to load config, %v", err)
}
client := s3.NewFromConfig(cfg, func(o *s3.Options) {
o.BaseEndpoint = aws.String("http://localhost:4566")
o.UsePathStyle = true
})
buckets, err := client.ListBuckets(context.TODO(), &s3.ListBucketsInput{})
if err != nil {
log.Fatalf("failed to list buckets, %v", err)
}
for _, bucket := range buckets.Buckets {
fmt.Println(*bucket.Name)
}
}
ソースコードの解説
1. 環境変数の設定
os.Setenv("AWS_ACCESS_KEY_ID", "test")
os.Setenv("AWS_SECRET_ACCESS_KEY", "test")
- LocalStackは認証情報を必要としないため、ダミーの値 (
test
) を環境変数として設定しています。
2. AWS SDKの設定
cfg, err := config.LoadDefaultConfig(context.TODO(),
config.WithRegion("us-east-1"),
)
-
config.LoadDefaultConfig
を使ってAWS SDKの設定を読み込みます。 - context.TODO()は、コンテキストを必要とする関数に対して、適切なコンテキストが未定の場合に使用されるコンテキストです。今回は特にコンテキストが決まっていないため、context.TODO()を使用しています。
-
WithRegion("us-east-1")
を指定していますが、LocalStackではこの設定は特に影響しません。test
などとしても問題ありません。
3. S3クライアントの作成
client := s3.NewFromConfig(cfg, func(o *s3.Options) {
o.BaseEndpoint = aws.String("http://localhost:4566")
o.UsePathStyle = true
})
- BaseEndpoint に
http://localhost:4566
を指定することで、LocalStackのS3エンドポイントを利用できます。 - LocalStack上のS3に接続する場合、バケットのURLは
http://localhost:4566/{バケット名}
の形式にする必要があります。この形式にするには、UsePathStyle = true
を設定する必要があります。- この設定を入れないと、エンドポイントが
https://{バケット名}.s3.amazonaws.com
となってしまい、LocalStack上のS3に接続することができません。
- この設定を入れないと、エンドポイントが
4. バケット一覧の取得
buckets, err := client.ListBuckets(context.TODO(), &s3.ListBucketsInput{})
-
ListBuckets
は、S3にあるすべてのバケットを取得するためのメソッドです。 -
ListBucketsInput{}
は、リクエストの入力パラメータですが、特に設定不要であるため、空の構造体を渡しています。 - バケットが存在しない場合は、
buckets.Buckets
は空のスライスになります。
5. バケット名の出力
for _, bucket := range buckets.Buckets {
fmt.Println(*bucket.Name)
}
-
buckets.Buckets
には取得したバケットの一覧が格納されており、ループを回してバケット名を表示しています。
Discussion