package storage import ( "context" "fmt" "io" "github.com/aws/aws-sdk-go-v2/aws" awsconfig "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/luxsin/app-api/internal/config" ) type S3Storage struct { client *s3.Client bucket string } func NewS3Storage(ctx context.Context, cfg config.S3Config) (*S3Storage, error) { var opts []func(*awsconfig.LoadOptions) error opts = append(opts, awsconfig.WithRegion(cfg.Region)) if cfg.AccessKeyID != "" && cfg.SecretAccessKey != "" { opts = append(opts, awsconfig.WithCredentialsProvider( credentials.NewStaticCredentialsProvider(cfg.AccessKeyID, cfg.SecretAccessKey, ""), )) } awsCfg, err := awsconfig.LoadDefaultConfig(ctx, opts...) if err != nil { return nil, fmt.Errorf("load aws config: %w", err) } return &S3Storage{ client: s3.NewFromConfig(awsCfg), bucket: cfg.Bucket, }, nil } func (s *S3Storage) GetObject(ctx context.Context, key string) ([]byte, error) { out, err := s.client.GetObject(ctx, &s3.GetObjectInput{ Bucket: aws.String(s.bucket), Key: aws.String(key), }) if err != nil { return nil, err } defer out.Body.Close() data, err := io.ReadAll(out.Body) if err != nil { return nil, fmt.Errorf("read s3 object body: %w", err) } return data, nil }