Drive (Storage)

Nimbus Drive provides a unified API for file storage across multiple backends: local filesystem, Amazon S3, Google Cloud Storage, Cloudflare R2, DigitalOcean Spaces, and Supabase. It allows you to swap storage providers without changing your code.

Installation & Setup

Drive is included by default when creating a new app. If you need to add it manually, install the plugin and register it in bin/server.go:

import "github.com/CodeSyncr/nimbus/plugins/drive"

// Register the plugin (uses environment variables for configuration)
app.Use(drive.New(nil))

Configuration

Set DRIVE_DISK in your .env file to choose the active storage backend. Then, provide the necessary credentials for that specific provider.

BackendDRIVE_DISK valueRequired Env Vars
Local Diskfs (default)None
Amazon S3s3S3_BUCKET, AWS_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
Google CloudgcsGCS_BUCKET, GCS_KEY
Cloudflare R2r2R2_BUCKET, R2_ENDPOINT, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY
DO SpacesspacesSPACES_BUCKET, SPACES_ENDPOINT, SPACES_KEY, SPACES_SECRET
SupabasesupabaseSUPABASE_STORAGE_BUCKET, SUPABASE_STORAGE_URL, SUPABASE_STORAGE_KEY

Usage

The drive.Use(disk) function returns a standard storage.Driver interface. Passing an empty string "" automatically uses the default disk specified by DRIVE_DISK.

import "github.com/CodeSyncr/nimbus/plugins/drive"

func handleUpload(c *http.Context) error {
    file, err := c.Request.FormFile("avatar")
    // ... handle err
    
    // Get the default configured disk (e.g., S3 in production, fs locally)
    disk, err := drive.Use("")
    
    // Store the file
    err = disk.Put("avatars/user-1.jpg", file)
    
    // Get the public URL for the newly stored file
    url, _ := disk.GetUrl("avatars/user-1.jpg")
    
    return c.JSON(200, map[string]string{"url": url})
}

Disk Operations API

MethodSignatureDescription
PutPut(path string, reader io.Reader) errorWrites a file to the configured disk. Automatically creates parent directories locally.
GetGet(path string) (io.ReadCloser, error)Streams the file for reading. You must Close() it when finished.
DeleteDelete(path string) errorRemoves the file.
ExistsExists(path string) (bool, error)Checks if the file exists on the disk.
GetUrlGetUrl(path string) (string, error)Returns a public URL for the file. For local fs, it prefixes with your RouteBasePath (e.g., /uploads/...).
GetSignedUrlGetSignedUrl(path string, dur time.Duration)Generates a temporary, secure URL valid for the specified duration (e.g. for private cloud buckets).

Local Disk Routing

When using the fs driver, Drive will store files in storage/app. The plugin automatically registers a static route to serve these files over HTTP if you enable it. By default, it mounts at /uploads.

To disable serving files or change the route, configure it in the plugin initialization:

app.Use(drive.New(&drive.Config{
    DefaultDisk:   "fs",
    ServeFiles:    true,         // automatically serve files via HTTP
    RouteBasePath: "/media",     // files will be served at /media/*
}))

Switching Disks Manually

If your app interacts with multiple storage backends simultaneously (e.g., storing user avatars locally but archiving invoices to S3), you can request a specific disk by name:

// Uses the backend defined by DRIVE_DISK
defaultDisk, _ := drive.Use("")

// Forces the S3 backend
s3Disk, err := drive.Use("s3")
err = s3Disk.Put("archives/2026/invoice.pdf", file)

// Forces local filesystem
localDisk, err := drive.Use("fs")
err = localDisk.Put("temp/cache.json", file)

Advanced: Raw Storage Driver

If you are building a CLI tool or a script that completely bypasses the Drive plugin and its cloud features, you can instantiate the low-level storage.LocalDriver manually. This is not recommended for normal web applications.

import "github.com/CodeSyncr/nimbus/storage"

func advanced() {
    driver := storage.NewLocalDriver("storage/app")
    
    // Low-level methods
    err := driver.Put("uploads/photo.jpg", file)
    ok, _ := driver.Exists("uploads/photo.jpg")
    driver.Delete("uploads/photo.jpg")
    
    rc, err := driver.Get("uploads/photo.jpg")
    if err == nil {
        defer rc.Close()
        // read from io.ReadCloser
    }
}

Unlike drive, the raw storage.LocalDriver has no concept of public URLs (GetUrl) or signed URLs. It only handles raw file I/O within a specified root directory.