Grocery is a framework for simple object storage with Redis in Go.

Features include:

  • Easy usage of structs as object models
  • Built-in support for lists, sets, and object pointers
  • Flexible custom datatypes
GitHub Docs
package main

import (
	"fmt"
	"sync"

	"github.com/redis/go-redis/v9"
	"github.com/nytimes/grocery"
)

// Supplier specifies how suppliers should be stored in Redis.
type Supplier struct {
	// Provides createdAt, updatedAt, and ID
	grocery.Base

	// All primitive types are supported. Grocery uses the field's name as the
	// key, with the first letter lowercased. Without grocery, this value could
	// later be retrieved with "HGET supplier: name"
	Name string
}

// Fruit specifies how fruits should be stored in Redis.
type Fruit struct {
	grocery.Base
	Name string

	// If another key is desired, it can be specified with a field tag.
	// This value can be retrieved with "HGET fruit: cost"
	Price float64 `grocery:"cost"`

	// Basic structures such as maps and lists are supported out of the
	// box as well. Maps are stored as their own key, so this value can be
	// retrieved with "HGETALL fruit::metadata"
	Metadata *grocery.Map

	// Pointers to other structs are supported. In Redis, the ID to the
	// struct is stored as a string. When this fruit is loaded with
	// grocery.Load, it will load the supplier struct as well.
	Supplier *Supplier
}

func main() {
	grocery.Init(&redis.Options{
		Addr: "localhost:6379",
	})

	supplier := &Supplier{
		Name: "R&D Fruit Co.",
	}

	id, _ := grocery.Store(supplier)
	fmt.Printf("Stored at supplier:%s\n", id)

	kv := sync.Map{}
	kv.Store("weight", 4.6)

	fruit := &Fruit{
		Name: "mango",
		Metadata: &grocery.Map{Map: kv},
		Supplier: supplier,
	}

	id, _ := grocery.Store(fruit)
	fmt.Printf("Stored at fruit:%s\n", id)
}