Quickstart
Get type-safe storage working in under 5 minutes.
Requirements
- Go 1.24 or higher
Installation
go get github.com/zoobz-io/grub
Install providers as needed:
# Key-value stores
go get github.com/zoobz-io/grub/redis
go get github.com/zoobz-io/grub/badger
go get github.com/zoobz-io/grub/bolt
# Blob storage
go get github.com/zoobz-io/grub/s3
go get github.com/zoobz-io/grub/minio
go get github.com/zoobz-io/grub/gcs
go get github.com/zoobz-io/grub/azure
# Vector search
go get github.com/zoobz-io/grub/qdrant
go get github.com/zoobz-io/grub/pinecone
go get github.com/zoobz-io/grub/milvus
go get github.com/zoobz-io/grub/weaviate
Basic Usage
Key-Value Store with Redis
package main
import (
"context"
"fmt"
"time"
"github.com/zoobz-io/grub"
"github.com/zoobz-io/grub/redis"
goredis "github.com/redis/go-redis/v9"
)
type Session struct {
UserID string `json:"user_id"`
Token string `json:"token"`
ExpiresAt int64 `json:"expires_at"`
}
func main() {
ctx := context.Background()
// Connect to Redis
client := goredis.NewClient(&goredis.Options{Addr: "localhost:6379"})
defer client.Close()
// Create type-safe store
sessions := grub.NewStore[Session](redis.New(client))
// Store with TTL
session := &Session{
UserID: "user:123",
Token: "abc123",
ExpiresAt: time.Now().Add(24 * time.Hour).Unix(),
}
_ = sessions.Set(ctx, "session:abc123", session, 24*time.Hour)
// Retrieve
s, _ := sessions.Get(ctx, "session:abc123")
fmt.Println(s.UserID) // user:123
}
Embedded Store with BadgerDB
No external services required:
package main
import (
"context"
"fmt"
"os"
"github.com/zoobz-io/grub"
"github.com/zoobz-io/grub/badger"
badgerdb "github.com/dgraph-io/badger/v4"
)
type Config struct {
Debug bool `json:"debug"`
Version string `json:"version"`
}
func main() {
ctx := context.Background()
// Open embedded database
opts := badgerdb.DefaultOptions("./data")
opts.Logger = nil // Silence logs
db, _ := badgerdb.Open(opts)
defer db.Close()
// Create store
configs := grub.NewStore[Config](badger.New(db))
// Store (TTL=0 means no expiration)
_ = configs.Set(ctx, "app:config", &Config{Debug: true, Version: "1.0"}, 0)
// Retrieve
cfg, _ := configs.Get(ctx, "app:config")
fmt.Printf("Debug: %v, Version: %s\n", cfg.Debug, cfg.Version)
// Cleanup
os.RemoveAll("./data")
}
Blob Storage with S3
package main
import (
"context"
"fmt"
"github.com/zoobz-io/grub"
"github.com/zoobz-io/grub/s3"
"github.com/aws/aws-sdk-go-v2/config"
awss3 "github.com/aws/aws-sdk-go-v2/service/s3"
)
type Document struct {
Title string `json:"title"`
Content string `json:"content"`
}
func main() {
ctx := context.Background()
// Configure AWS client
cfg, _ := config.LoadDefaultConfig(ctx)
client := awss3.NewFromConfig(cfg)
// Create bucket wrapper
docs := grub.NewBucket[Document](s3.New(client, "my-bucket"))
// Store object
_ = docs.Put(ctx, &grub.Object[Document]{
Key: "docs/readme.json",
ContentType: "application/json",
Data: Document{Title: "README", Content: "Hello, world!"},
})
// Retrieve
obj, _ := docs.Get(ctx, "docs/readme.json")
fmt.Println(obj.Data.Title) // README
}
Vector Search with Qdrant
package main
import (
"context"
"fmt"
"github.com/qdrant/go-client/qdrant"
"github.com/zoobz-io/grub"
grubqdrant "github.com/zoobz-io/grub/qdrant"
)
type Embedding struct {
Category string `json:"category"`
Source string `json:"source"`
}
func main() {
ctx := context.Background()
// Connect to Qdrant
client, _ := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
defer client.Close()
// Create type-safe index
embeddings := grub.NewIndex[Embedding](grubqdrant.New(client, grubqdrant.Config{
Collection: "documents",
}))
// Store vector with metadata
vector := []float32{0.1, 0.2, 0.3}
_ = embeddings.Upsert(ctx, "doc:1", vector, &Embedding{
Category: "tech",
Source: "blog",
})
// Similarity search
query := []float32{0.15, 0.25, 0.35}
results, _ := embeddings.Search(ctx, query, 10, nil)
for _, r := range results {
fmt.Printf("ID: %s, Score: %f\n", r.ID, r.Score)
}
}
What's Happening
- Provider wraps client —
redis.New(client)creates aStoreProvider,qdrant.New(client)creates aVectorProvider - Wrapper adds type safety —
grub.NewStore[T],grub.NewBucket[T],grub.NewIndex[T]wrap providers - Codec handles serialization — JSON by default, Gob available
- Operations return typed values —
Getreturns*T,Searchreturns[]*Vector[T]
Next Steps
- Core Concepts — Understand stores, buckets, databases, and indexes
- Providers Guide — Choose and configure providers
- API Reference — Complete method documentation