🎵

golangでlambdaでaws s3へアップロードしたい

2022/03/10に公開

目的:golangでs3へアップロード

方法:メモリにのせずにstreamでやる

なぜ?そのほうが効率がいいから。

実装していくことで大事なポイントはio.Pipeを使うということ。
このio.Pipeを使うことでchannelを使っていい感じにreaderとwriterのトンネル作ってくれるそうです。

pr, pw := io.Pipe()

実装例

package main

import (
	"errors"
	"fmt"
	"io"
	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/endpoints"
	"github.com/aws/aws-sdk-go/aws/session"
)

func handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	// まずはsessionを作成
	session, err := session.NewSession(&aws.Config{
		// region指定
		Region:      aws.String(endpoints.ApNortheast1RegionID),
		// credential指定 -> awsのクレデンシャルでadminというプロファイルを使う
		Credentials: credentials.NewSharedCredentials("", "admin"),
	})
	// s3managerつくります
	uploader := s3manager.NewUploader(session)
	
	// 今回の肝になるio pipeを生成
	pr, pw := io.Pipe()
	
	// bucket指定
	bucket := "dev"
	// file名
	key := "csv/test.csv"
	
	// テストデータ
	data := []string{"hello", "world", "for", "zenn"}
	go func() {
		// pipe使い終わったら閉じる
		defer pw.Close()
		for _, d := range data {
			// 書き込み
			pw.Write([]byte(d))
		}
	}()
	// 読み出しながれのアップロード
	req := s3manager.UploadInput{
		Bucket: &bucket,
		Key:    &key,
		Body:   pr,
	}
	_, err := uploader.Upload(&req)
	if err != nil {
		return
	}
}

Discussion