
There's no dedicated AIOZ Storage Go package either. The AIOZ storage go sdk is the official AWS SDK for Go v2, aws-sdk-go-v2, configured with a custom endpoint resolver and UsePathStyle: true. This quickstart covers the exact client setup AIOZ's own SDK documentation specifies, then uploading, listing, downloading, and deleting objects with it.
TL;DR:
aws-sdk-go-v2 (github.com/aws/aws-sdk-go-v2/service/s3), the same package used against Amazon S3 itself, no AIOZ-specific module exists.EndpointResolverWithOptionsFunc, a static credentials provider, and o.UsePathStyle = true on the s3.Client.aws-sdk-go-v2 S3 API, nothing AIOZ-specific past this point.No. AIOZ Storage's S3-compatible API works directly with aws-sdk-go-v2, the same official AWS SDK module used against Amazon S3. Install the pieces this guide uses with:
go get github.com/aws/aws-sdk-go-v2/aws
go get github.com/aws/aws-sdk-go-v2/config
go get github.com/aws/aws-sdk-go-v2/service/s3There's nothing AIOZ-specific to add on top, the same "it's just the standard SDK pointed elsewhere" pattern as AIOZ's JavaScript and Python SDK docs.
AIOZ's own SDK documentation specifies this exact configuration:
package main
import (
"context"
"log"
"os"
"strings"
"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() {
resolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
return aws.Endpoint{
URL: "https://s3.aiozstorage.network",
SigningRegion: "us-east-1",
}, nil
})
credentials := aws.CredentialsProviderFunc(func(ctx context.Context) (aws.Credentials, error) {
return aws.Credentials{
AccessKeyID: "YOUR_ACCESS_KEY_ID",
SecretAccessKey: "YOUR_SECRET_ACCESS_KEY",
}, nil
})
cfg, err := config.LoadDefaultConfig(context.TODO(),
config.WithCredentialsProvider(credentials),
config.WithEndpointResolverWithOptions(resolver),
)
if err != nil {
log.Fatal(err)
}
s3Client := s3.NewFromConfig(cfg, func(o *s3.Options) {
o.UsePathStyle = true
})
}Two settings matter more than the others here. SigningRegion: "us-east-1" is required even though AIOZ Storage isn't region-partitioned, the same placeholder-region pattern the JavaScript and Python SDKs use. And o.UsePathStyle = true isn't optional: without it, the client defaults to virtual-hosted-style requests (bucket.endpoint/key), which don't resolve against AIOZ Storage's single endpoint the way they do against AWS's per-region S3 endpoints. Leave it out and every request fails before it reaches your bucket.
AIOZ's docs show the upload as a full working example, opening a local file and passing it straight through as the request body:
filePath := "YOUR_FILE_PATH"
path := strings.Split(filePath, "/")
fileName := path[len(path)-1]
file, err := os.Open(filePath)
if err != nil {
log.Fatal(err)
}
defer file.Close()
_, err = s3Client.PutObject(context.TODO(), &s3.PutObjectInput{
Bucket: aws.String("your-bucket"),
Key: aws.String(fileName),
Body: file,
})
if err != nil {
log.Fatal(err)
}Body takes anything satisfying Go's io.Reader, an open file, a byte buffer, a network stream, so you're not limited to files already on disk. Every call above also takes a context.Context as its first argument, Go's standard mechanism for cancellation and deadlines; context.TODO() is fine for a quick script, but a real service should pass a request-scoped context so a slow upload can actually be cancelled instead of running to completion regardless.
Listing and downloading both follow the standard aws-sdk-go-v2 pattern, no AIOZ-specific parameters beyond the client config above:
func listFiles(ctx context.Context, client *s3.Client, bucket string) ([]string, error) {
var keys []string
paginator := s3.NewListObjectsV2Paginator(client, &s3.ListObjectsV2Input{
Bucket: aws.String(bucket),
})
for paginator.HasMorePages() {
page, err := paginator.NextPage(ctx)
if err != nil {
return nil, err
}
for _, obj := range page.Contents {
keys = append(keys, *obj.Key)
}
}
return keys, nil
}
func downloadFile(ctx context.Context, client *s3.Client, bucket, key, destPath string) error {
result, err := client.GetObject(ctx, &s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
if err != nil {
return err
}
defer result.Body.Close()
out, err := os.Create(destPath)
if err != nil {
return err
}
defer out.Close()
_, err = out.ReadFrom(result.Body)
return err
}ListObjectsV2 is paginated in aws-sdk-go-v2, which is why listing goes through s3.NewListObjectsV2Paginator instead of a single call, the SDK handles fetching additional pages internally as you call NextPage. GetObject returns the object body as an io.ReadCloser, so downloading means reading it into a destination file yourself rather than getting a ready-made local copy back.
func deleteFile(ctx context.Context, client *s3.Client, bucket, key string) error {
_, err := client.DeleteObject(ctx, &s3.DeleteObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
return err
}Same pattern as every other operation: build the input struct, call the client method. Like the S3 API generally, a delete against a key that doesn't exist still returns successfully rather than erroring, so this won't tell you whether the object was actually there beforehand.
aws-sdk-go-v2 returns typed errors you can match with Go's errors.As, rather than parsing an error string:
import "github.com/aws/aws-sdk-go-v2/service/s3/types"
_, err := s3Client.GetObject(ctx, &s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
if err != nil {
var noKey *types.NoSuchKey
if errors.As(err, &noKey) {
log.Printf("object %s does not exist in %s", key, bucket)
} else {
log.Fatal(err)
}
}The types package exposes specific error types per operation, NoSuchKey, NoSuchBucket, and similar, the Go SDK's equivalent of the named exception classes boto3 and the JavaScript SDK expose on their side of this same SDK family.
What Go module do I need for the AIOZ Storage Go SDK?github.com/aws/aws-sdk-go-v2, specifically its service/s3 package. No separate AIOZ-specific module exists.
Why does the S3 client need o.UsePathStyle = true for AIOZ Storage?
Without it, the client defaults to virtual-hosted-style request URLs (bucket.endpoint/key), which don't work against AIOZ Storage's single endpoint. UsePathStyle switches requests to endpoint/bucket/key instead.
Why does the endpoint resolver need a SigningRegion if AIOZ Storage isn't region-partitioned?
The SDK requires a signing region for its request-signing process regardless of target. AIOZ's own documentation sets it to us-east-1 as a placeholder, the same value used across its JavaScript and Python SDK docs.
Is ListObjectsV2 a single call or does it paginate?
It paginates. aws-sdk-go-v2 provides s3.NewListObjectsV2Paginator to handle fetching additional pages as you call NextPage, rather than returning every object in one response.
What does GetObject return when downloading?
An io.ReadCloser on the response body, not a ready-made local file. You read it into a destination file (or wherever you need the bytes) yourself.
How do I catch and identify S3 errors in the Go SDK?
Use errors.As against the typed errors in github.com/aws/aws-sdk-go-v2/service/s3/types, such as types.NoSuchKey or types.NoSuchBucket, instead of matching on error strings.
Does deleting a nonexistent key return an error?
No. Like the S3 API generally, DeleteObject returns successfully even if the key was never there, so it won't tell you whether anything was actually deleted.
Is the Go SDK setup different from the JavaScript or Python setup?
Same underlying pattern, different syntax: all three need a custom endpoint pointed at AIOZ Storage and a path-style addressing setting (UsePathStyle in Go, forcePathStyle in JavaScript, addressing_style: path in boto3's Config).

Automatic MIME type detection on AIOZ Storage uses Google Magika to identify a file's type from its content when Content-Type is missing. How it actually works.

The AIOZ storage developer platform in one place: three SDKs, a CLI, direct API access, two migration paths, and the one config pattern tying it all together.

The 3-2-1 backup rule: three copies, two media, one off-site. Why it still holds up, why ransomware forced a 3-2-1-1-0 update, and where AIOZ Storage fits.

RBAC vs ABAC vs capability-based access control: three different answers to who can do what. NIST defines the first two, AIOZ Storage macaroons are the third.

What is a CDN: a network of cached servers placed near users to cut latency. How it sits in front of an origin like S3, and where AIOZ Storage fits in.

Hot vs cold storage: hot tiers cost more to store but less to access, cold tiers flip that trade. How AWS and Azure structure it, and where AIOZ Storage fits.