Rene Nochebuena 3d12d18200 feat(minio): initial stable release v1.0.0 — Client interface, xerrors, GetObject, doc examples
Add Client interface with PutObject, GetObject, RemoveObject, PresignedGetObject, and
HandleError; Component now embeds Client with Native() as escape hatch for operations
not covered by the interface. Add xerrors dependency: HandleError maps minio-go error
codes to portable typed codes (NoSuchKey → ErrNotFound, AccessDenied →
ErrPermissionDenied, BucketAlreadyExists → ErrAlreadyExists, etc.). OnStop sets
c.mc = nil for lifecycle consistency. doc.go updated with launcher wiring, upload,
presigned URL, GetObject, and HandleError usage examples. API committed as stable.

What's included:
- Config with Endpoint, AccessKey, SecretKey, UseSSL, Bucket, Region (env-driven, embeddable)
- Transport field in Config for test injection (env:"-", nil uses minio-go default)
- Client interface: PutObject, GetObject, RemoveObject, PresignedGetObject, HandleError
- Component interface: launcher.Component + health.Checkable + Client + Native()
- New(logger, cfg) constructor for lifecycle registration via lc.Append
- Automatic bucket creation on OnStart if bucket does not exist
- Health check via BucketExists at LevelCritical priority
- HandleError: maps minio-go ErrorResponse codes to xerrors typed errors
- 21 unit tests using mock HTTP transport; no live server required
2026-05-19 21:42:30 -06:00

minio

MinIO (S3-compatible) client with go-kit launcher lifecycle and health check integration.

Install

go get code.nochebuena.dev/go/minio

Usage

package main

import (
    miniomw "code.nochebuena.dev/go/minio"
    "code.nochebuena.dev/go/health"
    "code.nochebuena.dev/go/launcher"
    "code.nochebuena.dev/go/logz"
)

func main() {
    logger := logz.New(logz.Options{})

    cfg := miniomw.Config{
        Endpoint:  "minio:9000",
        AccessKey: "minioadmin",
        SecretKey: "minioadmin",
        UseSSL:    false,
        Bucket:    "my-app-assets",
        Region:    "us-east-1",
    }

    mc := miniomw.New(logger, cfg)

    lc := launcher.New(logger)
    lc.Append(mc)

    lc.BeforeStart(func() error {
        // Register health check
        _ = health.NewHandler(logger, mc)

        // Use the native minio-go client for direct SDK operations
        native := mc.Native()
        _ = native // PutObject, RemoveObject, PresignedGetObject, etc.

        return nil
    })

    if err := lc.Run(); err != nil {
        panic(err)
    }
}

Config environment variables

Variable Required Default Description
MINIO_ENDPOINT Yes MinIO API host and port, e.g. minio:9000
MINIO_ACCESS_KEY Yes Access key (username)
MINIO_SECRET_KEY Yes Secret key (password)
MINIO_BUCKET Yes Default bucket; created at startup if absent
MINIO_USE_SSL No false Enable TLS for the connection
MINIO_REGION No us-east-1 Region; default covers all self-hosted MinIO

Lifecycle

Hook Behaviour
OnInit Constructs the minio-go SDK client; no network call
OnStart Checks whether the configured bucket exists; creates it if not
OnStop No-op — the minio-go client is stateless

Health check

HealthCheck(ctx) calls BucketExists on the configured bucket. Priority is health.LevelCritical.

Multiple buckets

Each Component is bound to one bucket for health checks and startup init. For multiple buckets, instantiate multiple components with different configs. Use object key namespacing (e.g. products/{id}/{uuid}.ext) for logical separation within a single bucket.

Direct SDK access

Native() returns the underlying *minio.Client from github.com/minio/minio-go/v7. Use it for all object operations:

native := mc.Native()

// Upload
_, err := native.PutObject(ctx, "my-bucket", "products/abc/img.jpg", reader, size,
    minio.PutObjectOptions{ContentType: "image/jpeg"})

// Delete
err = native.RemoveObject(ctx, "my-bucket", "products/abc/img.jpg",
    minio.RemoveObjectOptions{})

// Presigned URL (e.g. 1 hour)
url, err := native.PresignedGetObject(ctx, "my-bucket", "products/abc/img.jpg",
    time.Hour, nil)
Description
No description provided
Readme 41 KiB
2026-05-19 21:45:04 -06:00
Languages
Go 100%