Skip to main content

File Storage

VEF includes a storage abstraction, configurable providers, a built-in resource, a proxy middleware, and automatic file promotion helpers for CRUD flows.

Supported Providers

The storage module currently supports:

Provider valueMeaning
memoryin-memory storage
filesystemlocal filesystem storage
minioMinIO-backed object storage

If you do not configure a provider, the module defaults to memory.

storage.Service Interface

Application code works against storage.Service, not a provider-specific implementation.

The full service surface includes:

MethodPurpose
PutObject(ctx, opts)upload one object
GetObject(ctx, opts)read one object
DeleteObject(ctx, opts)delete one object
DeleteObjects(ctx, opts)batch delete
ListObjects(ctx, opts)list objects
GetPresignedURL(ctx, opts)generate a temporary presigned URL
CopyObject(ctx, opts)copy an object
MoveObject(ctx, opts)move an object
StatObject(ctx, opts)inspect object metadata
PromoteObject(ctx, tempKey)move a temp/ object into permanent storage

Option Types

The storage package exposes option structs for each operation:

Option typeUsed by
storage.PutObjectOptionsPutObject
storage.GetObjectOptionsGetObject
storage.DeleteObjectOptionsDeleteObject
storage.DeleteObjectsOptionsDeleteObjects
storage.ListObjectsOptionsListObjects
storage.PresignedURLOptionsGetPresignedURL
storage.CopyObjectOptionsCopyObject
storage.MoveObjectOptionsMoveObject
storage.StatObjectOptionsStatObject

Built-In Resource: sys/storage

The storage module also registers an RPC resource:

Resource
sys/storage

Current actions:

ActionPurpose
uploadupload one file
get_presigned_urlgenerate a presigned URL
delete_tempdelete a temporary object only
statinspect object metadata
listlist objects

See Built-in Resources for the exact action contracts.

Temporary Upload Model

The built-in upload path generates temporary object keys under the temp/ prefix using a date-partitioned layout.

Related public constants:

ConstantMeaning
storage.TempPrefixtemp/ prefix for temporary uploads
storage.MetadataKeyOriginalFilenamemetadata key storing the original uploaded filename

File Promotion

The public promotion abstraction is:

TypePurpose
storage.Promoter[T]promote and clean up file references across CRUD lifecycle transitions

Promoter scenario matrix:

Call patternMeaning
newModel != nil && oldModel == nilcreate flow
newModel != nil && oldModel != nilupdate flow
newModel == nil && oldModel != nildelete flow

Supported metadata field types:

Meta typeMeaning
uploaded_filedirect file field
richtextHTML content containing resource references
markdownMarkdown content containing resource references

Storage Events

The storage module publishes these file lifecycle events:

Event typeMeaning
vef.storage.file.promoteda file was promoted from temporary to permanent storage
vef.storage.file.deleteda file was deleted

Storage Proxy Middleware

The storage module contributes an app-level download proxy route:

Route
/storage/files/<key>

Important behavior:

  • this route is normal app middleware, not an RPC action
  • it does not automatically inherit API Bearer authentication
  • it URL-decodes the key path, fetches the object, sets Content-Type, emits cache headers, and streams the file

Minimal Service Example

package avatars

import (
"context"
"strings"

"github.com/coldsmirk/vef-framework-go/storage"
)

func SaveAvatar(ctx context.Context, svc storage.Service) error {
_, err := svc.PutObject(ctx, storage.PutObjectOptions{
Key: "avatars/user-1001.txt",
Reader: strings.NewReader("demo"),
Size: int64(len("demo")),
ContentType: "text/plain",
})

return err
}

Practical Advice

  • use storage.Service in application code, not provider-specific implementations
  • treat temp/ uploads as a staging area, not as a permanent object location
  • document the /storage/files/<key> route separately from RPC resources
  • if your model carries file references, prefer integrating through storage.NewPromoter(...) instead of ad hoc cleanup logic

Next Step

Read Custom Handlers if you want to combine direct storage.Service usage with business-specific upload workflows.