Files
storage-minio/README.md
T
Rene Nochebuena 2a9cb9132b chore(storage-minio): bump einherjar deps to v1.1.0 (framework version alignment) (#1)
Patch of the coordinated framework release: einherjar modules move to v1.1.0
in lockstep, so storage-minio is bumped alongside the rest.

- go.mod: contracts, core -> v1.1.0 (via go get + go mod tidy)

No code or API changes. ModuleVersion() reports v1.1.0 automatically from
build info once tagged. Badge bumped to v1.1.0.

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

126 lines
3.4 KiB
Markdown

# einherjar/storage-minio
[![version](https://img.shields.io/badge/version-v1.1.0-5C4EE5?style=flat-square)](https://code.nochebuena.dev/einherjar/storage-minio)
[![license](https://img.shields.io/badge/license-AGPL--3.0-22863A?style=flat-square)](LICENSE)
[![go](https://img.shields.io/badge/Go-1.26+-00ADD8?style=flat-square&logo=go&logoColor=white)](https://go.dev)
[![health](https://img.shields.io/badge/health-critical-D73A49?style=flat-square)]()
> 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
```go
import storageminio "code.nochebuena.dev/einherjar/storage-minio"
s := storageminio.New(logger, storageminio.DefaultConfig())
launcher.Append(s) // OnInit connects; OnStop is a no-op (stateless client)
health.Register(s) // BucketExists check; LevelCritical
```
### Uploading
```go
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
```go
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)
```go
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
```go
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:
```go
native := s.Native() // *miniogo.Client
```
Callers that use `Native()` must import `github.com/minio/minio-go/v7` directly.
### Error handling
```go
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
```bash
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.*