Skip to main content

Go (aws-sdk-go-v2)

Fil One is fully compatible with aws-sdk-go-v2. Configure the client to point at the Fil One endpoint and use the standard S3 API.

Installation

go get github.com/aws/aws-sdk-go-v2/aws
go get github.com/aws/aws-sdk-go-v2/credentials
go get github.com/aws/aws-sdk-go-v2/service/s3
go get github.com/aws/aws-sdk-go-v2/service/s3/types

Client configuration

package main

import (
"os"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/s3"
)

func newClient() *s3.Client {
return s3.New(s3.Options{
BaseEndpoint: aws.String("https://eu-west-1.s3.fil.one"),
Region: "eu-west-1",
Credentials: credentials.NewStaticCredentialsProvider(
os.Getenv("FIL_ACCESS_KEY"),
os.Getenv("FIL_SECRET_KEY"),
"",
),
UsePathStyle: true,
})
}

Set FIL_ACCESS_KEY and FIL_SECRET_KEY as environment variables. Never hardcode credentials in source code.

Core operations

Create a bucket

_, err := client.CreateBucket(ctx, &s3.CreateBucketInput{
Bucket: aws.String("my-bucket"),
})

Upload an object

import (
"bytes"
"os"
)

// Upload bytes
_, err := client.PutObject(ctx, &s3.PutObjectInput{
Bucket: aws.String("my-bucket"),
Key: aws.String("data/file.json"),
Body: bytes.NewReader([]byte(`{"key":"value"}`)),
ContentType: aws.String("application/json"),
})

// Upload a file
f, _ := os.Open("report.pdf")
defer f.Close()

_, err = client.PutObject(ctx, &s3.PutObjectInput{
Bucket: aws.String("my-bucket"),
Key: aws.String("reports/report.pdf"),
Body: f,
ContentType: aws.String("application/pdf"),
})

Download an object

import (
"io"
"os"
)

result, err := client.GetObject(ctx, &s3.GetObjectInput{
Bucket: aws.String("my-bucket"),
Key: aws.String("reports/report.pdf"),
})
if err != nil {
// handle error
}
defer result.Body.Close()

out, _ := os.Create("local-report.pdf")
defer out.Close()
io.Copy(out, result.Body)

List objects

paginator := s3.NewListObjectsV2Paginator(client, &s3.ListObjectsV2Input{
Bucket: aws.String("my-bucket"),
})

for paginator.HasMorePages() {
page, err := paginator.NextPage(ctx)
if err != nil {
// handle error
}
for _, obj := range page.Contents {
fmt.Println(*obj.Key, obj.Size)
}
}

Delete an object

_, err := client.DeleteObject(ctx, &s3.DeleteObjectInput{
Bucket: aws.String("my-bucket"),
Key: aws.String("reports/report.pdf"),
})

Presigned URLs

import "github.com/aws/aws-sdk-go-v2/service/s3"

presigner := s3.NewPresignClient(client)

// Download URL valid for 1 hour
downloadReq, err := presigner.PresignGetObject(ctx, &s3.GetObjectInput{
Bucket: aws.String("my-bucket"),
Key: aws.String("reports/report.pdf"),
}, s3.WithPresignExpires(time.Hour))

// Upload URL valid for 15 minutes
uploadReq, err := presigner.PresignPutObject(ctx, &s3.PutObjectInput{
Bucket: aws.String("my-bucket"),
Key: aws.String("uploads/new-file.txt"),
}, s3.WithPresignExpires(15*time.Minute))

Error handling

import (
"errors"
"github.com/aws/smithy-go"
)

_, err := client.GetObject(ctx, &s3.GetObjectInput{
Bucket: aws.String("my-bucket"),
Key: aws.String("missing.txt"),
})
if err != nil {
var apiErr smithy.APIError
if errors.As(err, &apiErr) {
fmt.Println(apiErr.ErrorCode(), apiErr.ErrorMessage())
}
}

See the Error Reference for a full list of error codes.