Skip to content

Glowing-Pixels-UG/just-storage-go-sdk

Repository files navigation

JustStorage Go SDK

A production-ready Go client library for the JustStorage object storage service.

Features

  • Full API Coverage: Upload, download, list, and delete operations
  • Streaming Support: Efficient streaming for large files
  • Type-Safe: Strongly typed structs matching the API
  • Authentication: Support for JWT Bearer tokens and API keys
  • Error Handling: Comprehensive error types with helper functions
  • Context Support: Full context.Context support for cancellation and timeouts
  • Production Ready: Follows Go best practices and conventions

Installation

go get github.com/just-storage/go-sdk

Quick Start

package main

import (
    "context"
    "fmt"
    "io"
    "os"
    
    "github.com/just-storage/go-sdk"
)

func main() {
    // Create client with Bearer token
    client, err := sdk.NewClientWithBearerToken(
        "http://localhost:8080",
        "your-jwt-token",
    )
    if err != nil {
        panic(err)
    }

    ctx := context.Background()

    // Upload a file
    file, _ := os.Open("model.bin")
    defer file.Close()

    obj, err := client.Upload(ctx, file, sdk.UploadOptions{
        Namespace:    "models",
        TenantID:     "acme-corp",
        Key:          "llama-3.1-8b",
        StorageClass: sdk.StorageClassHot,
    })
    if err != nil {
        panic(err)
    }

    fmt.Printf("Uploaded: %s\n", obj.ID)

    // Download the object
    reader, metadata, err := client.Download(ctx, obj.ID, "acme-corp")
    if err != nil {
        panic(err)
    }
    defer reader.Close()

    output, _ := os.Create("downloaded.bin")
    defer output.Close()

    io.Copy(output, reader)
    fmt.Printf("Downloaded %d bytes\n", metadata.SizeBytes)
}

Authentication

The SDK supports three authentication methods:

JWT Bearer Token

client, err := sdk.NewClientWithBearerToken(
    "http://localhost:8080",
    "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
)

API Key

client, err := sdk.NewClientWithAPIKey(
    "http://localhost:8080",
    "your-api-key",
)

No Authentication (Development)

client, err := sdk.NewClientWithoutAuth("http://localhost:8080")

Operations

Upload

Upload an object with streaming support:

file, _ := os.Open("data.bin")
defer file.Close()

obj, err := client.Upload(ctx, file, sdk.UploadOptions{
    Namespace:    "models",
    TenantID:     "acme-corp",
    Key:          "my-model",  // Optional
    StorageClass: sdk.StorageClassHot,  // Optional, defaults to "hot"
})

Download

Download by object ID:

reader, metadata, err := client.Download(ctx, objectID, tenantID)
if err != nil {
    return err
}
defer reader.Close()

// Stream to file
output, _ := os.Create("output.bin")
defer output.Close()
io.Copy(output, reader)

Or download directly to a writer:

output, _ := os.Create("output.bin")
defer output.Close()

metadata, err := client.DownloadToWriter(ctx, objectID, tenantID, output)

Download by key:

reader, metadata, err := client.DownloadByKey(ctx, "models", "acme-corp", "llama-3.1-8b")

List

List objects with pagination:

limit := int64(50)
offset := int64(0)

response, err := client.List(ctx, sdk.ListOptions{
    Namespace: "models",
    TenantID:  "acme-corp",
    Limit:     &limit,
    Offset:    &offset,
})

for _, obj := range response.Objects {
    fmt.Printf("%s: %s\n", obj.ID, obj.Key)
}

Delete

Delete an object:

err := client.Delete(ctx, objectID, tenantID)
if err != nil {
    return err
}

Health Checks

health, err := client.Health(ctx)
fmt.Printf("Status: %s\n", health.Status)

readiness, err := client.Readiness(ctx)
fmt.Printf("Database: %s\n", readiness.Database)

Error Handling

The SDK provides structured error handling:

obj, err := client.Upload(ctx, file, opts)
if err != nil {
    if sdk.IsNotFound(err) {
        fmt.Println("Object not found")
    } else if sdk.IsUnauthorized(err) {
        fmt.Println("Authentication failed")
    } else if sdk.IsBadRequest(err) {
        fmt.Println("Invalid request")
    } else {
        fmt.Printf("Error: %v\n", err)
    }
    return
}

Error types include:

  • Code: Error code (e.g., "NOT_FOUND", "UNAUTHORIZED")
  • Message: Human-readable message
  • Details: Additional error details
  • Status: HTTP status code

Advanced Usage

Custom HTTP Client

httpClient := &http.Client{
    Timeout: 60 * time.Second,
    Transport: &http.Transport{
        MaxIdleConns: 100,
    },
}

client, err := sdk.NewClient(sdk.Config{
    BaseURL:    "http://localhost:8080",
    HTTPClient: httpClient,
    AuthToken:  "your-token",
    AuthType:   sdk.AuthTypeBearer,
})

Context with Timeout

ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

obj, err := client.Upload(ctx, file, opts)

Streaming Large Files

The SDK supports streaming for efficient memory usage:

// Upload from a reader (e.g., from another API)
reader := getDataFromSomewhere()
obj, err := client.Upload(ctx, reader, opts)

// Download to a writer (e.g., to another API)
writer := sendDataSomewhere()
metadata, err := client.DownloadToWriter(ctx, objectID, tenantID, writer)

Storage Classes

  • sdk.StorageClassHot: Frequently accessed data (default)
  • sdk.StorageClassCold: Archive data, lower cost

Object Status

Objects transition through states:

  • WRITING: Upload in progress
  • COMMITTED: Available for download
  • DELETING: Deletion requested
  • DELETED: Physically removed

Only COMMITTED objects are visible in list/download operations.

Best Practices

  1. Always use context: Pass context for cancellation and timeouts
  2. Close readers: Always close download readers to free resources
  3. Handle errors: Check errors and use helper functions for common cases
  4. Stream large files: Use streaming for files > 100MB
  5. Set appropriate storage class: Use "cold" for archives, "hot" for active data

Examples

See the examples/ directory for complete examples:

  • upload_example.go: Upload a file
  • download_example.go: Download and save a file
  • list_example.go: List and paginate objects
  • streaming_example.go: Stream data between services

License

See LICENSE file for details.

Contributing

Contributions welcome! Please see CONTRIBUTING.md for guidelines.

Releases

No releases published

Sponsor this project

Packages

 
 
 

Contributors

Languages