Welcome to the Tigris Storage SDK for Go! This package contains high-level wrappers and helpers to help you take advantage of all of Tigris' features.
Tigris is a cloud storage service that provides a simple, scalable, and secure object storage solution. It is based on the S3 API, but has additional features that need these helpers.
This SDK provides the main storage package containing the Tigris client with S3-compatible methods plus Tigris-specific features like bucket forking, snapshots, soft delete, and object renaming.
go get github.com/tigrisdata/storage-gopackage main
import (
"context"
"fmt"
"log"
storage "github.com/tigrisdata/storage-go"
)
func main() {
ctx := context.Background()
// Create a new Tigris client
client, err := storage.New(ctx)
if err != nil {
log.Fatal(err)
}
// Use the client like you would use AWS S3 client
// plus Tigris-specific features (see below)
fmt.Println("Connected to Tigris!")
}The New() function creates a new S3 client optimized for interactions with Tigris. It accepts functional options to configure the client:
client, err := storage.New(ctx,
storage.WithFlyEndpoint(), // Use fly.io optimized endpoint
storage.WithGlobalEndpoint(), // Use globally available endpoint (default)
storage.WithRegion("auto"), // Specify a region
storage.WithAccessKeypair(key, secret), // Set access credentials
)| Option | Description |
|---|---|
WithFlyEndpoint() |
Connect to Tigris' fly.io optimized endpoint. If you are deployed to fly.io, this zero-rates your traffic to Tigris. |
WithGlobalEndpoint() |
Connect to Tigris' globally available endpoint (https://t3.storage.dev). This is the default. |
WithRegion(region) |
Statically specify a region for interacting with Tigris. You will almost certainly never need this. |
WithAccessKeypair(accessKeyID, secretAccessKey) |
Specify a custom access key and secret access key. Useful when loading credentials from non-standard locations. |
Tigris supports bucket snapshots and forking, allowing you to create point-in-time copies of buckets and branch from them.
output, err := client.CreateSnapshotEnabledBucket(ctx, &s3.CreateBucketInput{
Bucket: aws.String("my-bucket"),
})output, err := client.CreateBucketSnapshot(ctx, "Initial backup", &s3.CreateBucketInput{
Bucket: aws.String("my-bucket"),
})
// output.SnapshotVersion holds the version returned by Tigris.// Creates a new bucket "my-bucket-fork" as a fork of "my-bucket"
output, err := client.CreateBucketFork(ctx, "my-bucket", "my-bucket-fork")snapshots, err := client.ListBucketSnapshots(ctx, "my-bucket")info, err := client.HeadBucketForkOrSnapshot(ctx, &s3.HeadBucketInput{
Bucket: aws.String("my-bucket"),
})
// info.SnapshotsEnabled - true if snapshots are enabled
// info.SourceBucket - The bucket this was forked from
// info.SourceBucketSnapshot - The snapshot this was forked from
// info.IsForkParent - true if there are forks of this bucketSoft delete moves a deleted object or bucket into a recoverable state for a retention window. The window is 7 days by default. A custom window must be between 7 and 90 days. Soft delete is a bucket-level setting, so it covers the bucket and every object in it.
// Default 7-day retention window
_, err := client.CreateBucketWithSoftDelete(ctx, &storage.CreateBucketWithSoftDeleteInput{
CreateBucketInput: &s3.CreateBucketInput{
Bucket: aws.String("my-bucket"),
},
})
// Custom 30-day retention window
_, err = client.CreateBucketWithSoftDelete(ctx, &storage.CreateBucketWithSoftDeleteInput{
CreateBucketInput: &s3.CreateBucketInput{
Bucket: aws.String("my-other-bucket"),
},
RetentionDays: 30,
})_, err := client.SetBucketSoftDelete(ctx, &storage.SetBucketSoftDeleteInput{
Bucket: "my-bucket",
Enabled: true,
RetentionDays: 30, // omit for the default 7-day window
})listed, err := client.ListSoftDeletedObjects(ctx, &storage.ListSoftDeletedObjectsInput{
Bucket: "my-bucket",
Prefix: "logs/", // optional
})
// listed.Objects[i].Key - object key
// listed.Objects[i].VersionID - version to restore or permanently delete
// listed.Objects[i].Size - original size in bytes
// listed.Objects[i].LastModified - time the object was soft-deleted
// listed.IsTruncated - true if more pages are available
// Restore the most recent soft-deleted version
_, err = client.RestoreSoftDeletedObject(ctx, &storage.RestoreSoftDeletedObjectInput{
Bucket: "my-bucket",
Key: "my-key",
})
// Restore one specific version
_, err = client.RestoreSoftDeletedObject(ctx, &storage.RestoreSoftDeletedObjectInput{
Bucket: "my-bucket",
Key: "my-key",
VersionID: listed.Objects[0].VersionID,
})To read the next page, pass listed.NextKeyMarker and listed.NextVersionIDMarker back as KeyMarker and VersionIDMarker.
A soft-deleted bucket keeps its name reserved until the retention window expires.
RetentionDays is the window the bucket was configured with. It is not a
countdown: a bucket deleted 6 days ago with a 30-day window still reports 30.
listed, err := client.ListSoftDeletedBuckets(ctx, nil)
// listed.Buckets[i].Name - bucket to restore
// listed.Buckets[i].RetentionDays - the configured window in days
_, err = client.RestoreBucket(ctx, &storage.RestoreBucketInput{
Bucket: "my-bucket",
})ForceDeleteBucket deletes a bucket and its contents in one call. If soft delete is enabled on the bucket, RestoreBucket can recover it.
Caution
Do not call ForceDeleteBucket on a bucket without soft delete. The bucket and every object in it are removed permanently. Support cannot recover them.
_, err := client.ForceDeleteBucket(ctx, &s3.DeleteBucketInput{
Bucket: aws.String("my-bucket"),
})PermanentlyDeleteObject removes one soft-deleted version before its retention window expires. The version ID is required. Get it from ListSoftDeletedObjects.
Caution
Do not call PermanentlyDeleteObject unless you accept the loss of the data. The version is removed permanently. Support cannot recover it.
_, err := client.PermanentlyDeleteObject(ctx, "my-bucket", "my-key", "1775929768707198086")ListSoftDeletedObjects, ListSoftDeletedBuckets, RestoreSoftDeletedObject, RestoreBucket, and SetBucketSoftDelete send their requests to Tigris endpoints that the S3 SDK cannot express. When Tigris rejects one of these requests, the method returns a *storage.APIError. This type implements smithy.APIError, so errors.As reads it the same way it reads an error from the embedded S3 client:
_, err := client.RestoreBucket(ctx, &storage.RestoreBucketInput{Bucket: "my-bucket"})
var apiErr smithy.APIError
if errors.As(err, &apiErr) && apiErr.ErrorCode() == "NoSuchBucket" {
// the bucket is gone
}For the HTTP status code and the request ID, match the concrete type:
var apiErr *storage.APIError
if errors.As(err, &apiErr) {
log.Printf("HTTP %d %s: %s (request %s)",
apiErr.StatusCode, apiErr.Code, apiErr.Message, apiErr.RequestID)
}Tigris supports in-place object renaming without copying data:
_, err := client.RenameObject(ctx, &s3.CopyObjectInput{
Bucket: aws.String("my-bucket"),
CopySource: aws.String("my-bucket/old-name.txt"),
Key: aws.String("new-name.txt"),
})For more information on Tigris features, see:
See LICENSE for details.