Go
AWS
S3

GoでAmazon S3をKVSとして使う


これはなに

永続化が必要なバイナリKVSとしてAmazon S3を使いたい場合があります。

セッションの取り回しや、aws.WriteAtBufferやエラーがトリッキーなのでスニペットです。

package s3kvs

import (
"bytes"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
)

var PersistentS3Store = &S3Store{}

type S3Store struct {
Bucket string
Uploader *s3manager.Uploader
Downloader *s3manager.Downloader
}

func (s *S3Store) Init(bucket, region string) (err error) {
s.Bucket = bucket

sess, err := session.NewSession(&aws.Config{
Region: aws.String(region),
})
if err != nil {
return
}

s.Uploader = s3manager.NewUploader(sess)
s.Downloader = s3manager.NewDownloader(sess)

return
}

func (s *S3Store) Set(key string, body []byte) (err error) {
params := &s3manager.UploadInput{
Bucket: aws.String(s.Bucket),
Key: aws.String(key),
Body: bytes.NewReader(body),
}

_, err = s.Uploader.Upload(params)
return
}

func (s *S3Store) Get(key string) ([]byte, error) {
buffer := aws.NewWriteAtBuffer([]byte{})

_, err := s.Downloader.Download(buffer, &s3.GetObjectInput{
Bucket: aws.String(s.Bucket),
Key: aws.String(key),
})
if err != nil {
if aerr, ok := err.(awserr.Error); ok && aerr.Code() == "NoSuchKey" {
return nil, nil
}
return nil, err
}

return buffer.Bytes(), nil
}