ss-keel-storage
ss-keel-storage provides a Storage implementation with a unified API across AWS S3, Google Cloud Storage (GCS), and local disk. Switch providers by changing config — your application code stays the same.
Implements: Storage
Planned Installation
Section titled “Planned Installation”go get github.com/slice-soft/ss-keel-storagePlanned Usage
Section titled “Planned Usage”AWS S3
Section titled “AWS S3”import "github.com/slice-soft/ss-keel-storage"
storage, err := ssstorage.NewS3(ssstorage.S3Config{ Bucket: os.Getenv("S3_BUCKET"), Region: os.Getenv("AWS_REGION"), AccessKey: os.Getenv("AWS_ACCESS_KEY_ID"), SecretKey: os.Getenv("AWS_SECRET_ACCESS_KEY"),})Google Cloud Storage
Section titled “Google Cloud Storage”storage, err := ssstorage.NewGCS(ssstorage.GCSConfig{ Bucket: os.Getenv("GCS_BUCKET"), CredentialsFile: os.Getenv("GOOGLE_APPLICATION_CREDENTIALS"),})Local Disk (development)
Section titled “Local Disk (development)”storage, err := ssstorage.NewLocal(ssstorage.LocalConfig{ BaseDir: "./uploads", BaseURL: "http://localhost:3000/uploads",})Using Storage
Section titled “Using Storage”All providers share the same interface:
// Uploadfile, _ := c.FormFile("avatar")src, _ := file.Open()defer src.Close()
err := storage.Put(ctx, "avatars/"+userID+".jpg", src, file.Size, "image/jpeg")
// Generate a signed URL (expires in 1 hour)url, err := storage.URL(ctx, "avatars/"+userID+".jpg", time.Hour)
// Downloadreader, err := storage.Get(ctx, "avatars/"+userID+".jpg")defer reader.Close()
// Deleteerr := storage.Delete(ctx, "avatars/"+userID+".jpg")
// File infoobj, err := storage.Stat(ctx, "avatars/"+userID+".jpg")// obj.Size, obj.ContentType, obj.LastModifiedIn a Handler
Section titled “In a Handler”func (c *AvatarController) upload(ctx *core.Ctx) error { file, err := ctx.FormFile("avatar") if err != nil { return core.BadRequest("no file provided") }
src, _ := file.Open() defer src.Close()
key := fmt.Sprintf("avatars/%s.jpg", uuid.New()) if err := c.storage.Put(ctx.Context(), key, src, file.Size, file.Header.Get("Content-Type")); err != nil { return core.Internal("upload failed", err) }
url, _ := c.storage.URL(ctx.Context(), key, 365*24*time.Hour) return ctx.Created(map[string]string{"url": url})}