Rene Nochebuena abeefd9810 docs(storage-minio): fix fictional launcher.Register/health.Register in doc examples (#2)
The package-doc examples showed a fictional launcher.Register / health.Register
API (and launcher.Append as a package func). Corrected to the real wiring:
lc.Append + web/health.NewHandler(...).ServeHTTP.

Documentation-only. No code, API, or dependency changes; version stays v1.1.0
(the v1.1.0 tag is moved to include this fix). Verified by compiling the
corrected pattern against the real API.

Reviewed-on: #2
Co-authored-by: Rene Nochebuena Guerrero <rene@nochebuena.dev>
Co-committed-by: Rene Nochebuena Guerrero <rene@nochebuena.dev>
2026-08-07 22:19:14 -06:00

einherjar/storage-minio

version license go health

The shield does not care who forged it. It holds what it is given and gives it back unchanged.

code.nochebuena.dev/einherjar/storage-minio is the MinIO/S3 object storage component of the Einherjar framework. It wraps minio-go/v7 behind a lifecycle-aware Component with four common operations — upload, download, delete, and presigned URLs. For anything beyond that scope, Native() returns the raw *miniogo.Client.


Usage

Setup

import storageminio "code.nochebuena.dev/einherjar/storage-minio"

s := storageminio.New(logger, storageminio.DefaultConfig())
lc.Append(s)   // OnInit connects; OnStop is a no-op (stateless client)
// s is observability.Checkable (BucketExists check, LevelCritical):
srv.Get("/health", health.NewHandler(logger, s).ServeHTTP)

Uploading

import miniogo "github.com/minio/minio-go/v7"

info, err := s.PutObject(ctx, "my-bucket", "uploads/photo.jpg", reader, size, miniogo.PutObjectOptions{
    ContentType: "image/jpeg",
})

Downloading

obj, err := s.GetObject(ctx, "my-bucket", "uploads/photo.jpg", miniogo.GetObjectOptions{})
if err != nil {
    return s.HandleError(err)
}
defer obj.Close()

Presigned URL (time-limited public access)

url, err := s.PresignedGetObject(ctx, "my-bucket", "uploads/photo.jpg", 15*time.Minute, nil)
// url is a *url.URL — call url.String() to get the string form

Deleting

err := s.RemoveObject(ctx, "my-bucket", "uploads/photo.jpg", miniogo.RemoveObjectOptions{})

Native escape hatch

For multipart uploads, bucket management, or any operation not in Provider, use the raw client:

native := s.Native() // *miniogo.Client

Callers that use Native() must import github.com/minio/minio-go/v7 directly.

Error handling

if err := s.HandleError(someErr); err != nil {
    // minio-go error responses mapped to xerrors:
    // NoSuchKey / NoSuchBucket → ErrNotFound
    // AccessDenied             → ErrPermissionDenied
    // context.Canceled         → ErrCancelled
    // context.DeadlineExceeded → ErrDeadlineExceeded
}

HandleError is also available as a package-level function: storageminio.HandleError(err).


Environment variables

Variable Required Default Description
EINHERJAR_MINIO_ENDPOINT Yes MinIO/S3 endpoint (host:port or domain)
EINHERJAR_MINIO_ACCESS_KEY Yes Access key ID
EINHERJAR_MINIO_SECRET_KEY Yes Secret access key
EINHERJAR_MINIO_BUCKET Yes Default bucket for health check
EINHERJAR_MINIO_USE_SSL No false Use TLS
EINHERJAR_MINIO_REGION No us-east-1 Bucket region

Dependency graph

contracts  (zero dependencies)
    ↑
  core
    ↑
storage-minio  (contracts, core, minio-go/v7)
    ↑
  your app

Verification

cd storage-minio/
go build ./...
go vet ./...
go test ./...
gofmt -l .

The artifact survives the battle that created it. Store it well. Someone will need it after you are gone.

S
Description
MinIO/S3 object storage component with presigned URLs and native client escape hatch
Readme AGPL-3.0
147 KiB
2026-08-12 15:55:23 -06:00
Languages
Go 100%