Go SDK · v0.1
Go SDK
Official Go client for SapixDB. Zero external dependencies — uses only the standard library. Context-aware, goroutine-safe, Go 1.21+.
Installation
shell
go get github.com/sapixdb/sapixdb-go
Then import the package in your code:
Go
import sapixdb "github.com/sapixdb/sapixdb-go"
Quick Start
Go
package main
import (
"context"
"fmt"
sapixdb "github.com/sapixdb/sapixdb-go"
)
func main() {
ctx := context.Background()
db := sapixdb.New(sapixdb.Config{
URL: "http://localhost:7475",
Agent: "my-app",
})
// Check connection
fmt.Println(db.Ping(ctx)) // true
// Write a record
record, err := db.Collection("products").Write(ctx, map[string]any{
"name": "Classic T-Shirt",
"price": 29.99,
"stock": 100,
})
if err != nil {
panic(err)
}
fmt.Println(record.ID) // "nuc_abc123"
fmt.Println(record.Hash) // "sha3:e7f2a1..." — cryptographic proof
// Read latest records
products, _ := db.Collection("products").Latest(ctx, nil)
// Filter
shirts, _ := db.Collection("products").Find(ctx, map[string]any{
"category": "apparel",
}, 0)
// Time travel
snapshot, _ := db.Collection("orders").
AsOf("2024-01-01T00:00:00Z").
Latest(ctx, nil)
_ = products
_ = shirts
_ = snapshot
}Client Configuration
Go
db := sapixdb.New(sapixdb.Config{
URL: "http://localhost:7475", // SapixDB agent URL (required)
Agent: "my-app", // agent ID (required)
Headers: map[string]string{ // extra headers (optional)
"X-Api-Key": "secret",
},
Timeout: 30 * time.Second, // default: 10s
})Collection API
.Write(ctx, data)→ *WriteResult, errorAppend a new record. Returns
WriteResult with ID, Hash, PrevHash, Timestamp. Nothing is ever overwritten — every write is permanent..WriteBatch(ctx, records)→ []*WriteResult, errorWrite multiple records sequentially. Returns results in order; stops on first error.
.Get(ctx, recordID)→ *NucleotideRecord, errorFetch by nucleotide ID. Returns
*SapixNotFoundError if missing..Latest(ctx, filter)→ []NucleotideRecord, errorCurrent (most recent) version of every record. Pass
nil for no filter..History(ctx, filter)→ []NucleotideRecord, errorFull append-only history — every version ever written.
.Find(ctx, filter, limit)→ []NucleotideRecord, errorFilter records (latest version only). Pass
0 for no limit..FindOne(ctx, filter)→ *NucleotideRecord, errorFirst match or
nil. Never errors on empty result..AsOf(timestamp)→ *CollectionQueryScope reads to a point in time. Returns a query object with
.Latest(), .All(), .Find(), .FindOne().Time Travel
Go
import "time"
// 30 minutes ago
ts := time.Now().Add(-30 * time.Minute).UTC().Format(time.RFC3339)
snapshot, err := db.Collection("orders").
AsOf(ts).
Find(ctx, map[string]any{"customer_id": "cust_001"}, 0)
// Returns orders exactly as they existed 30 minutes agoGraph Relationships
db.Graph.Relate(ctx, src, dst, edgeType, weight)→ errorCreate a typed directed edge. Cleanest way to express relationships.
db.Graph.Traverse(ctx, fromID, TraverseOptions)→ *TraverseResult, errorWalk the graph. Returns
TraverseResult with .Nodes and .Edges. Direction: "outbound" | "inbound" | "both".db.Graph.Neighbors(ctx, nodeID, direction)→ []NucleotideRecord, errorDirect neighbours — depth=1 shortcut.
Go
// Link order → customer
_ = db.Graph.Relate(ctx, order.ID, customer.ID, "placed_by", 1.0)
_ = db.Graph.Relate(ctx, order.ID, product.ID, "contains", 1.0)
// Find everything connected to a customer (depth 2)
result, err := db.Graph.Traverse(ctx, customer.ID, sapixdb.TraverseOptions{
Depth: 2,
Direction: "inbound",
})
fmt.Println(result.Nodes) // []NucleotideRecord
fmt.Println(result.Edges) // []GraphEdgeAgent Ingest
Go — log every AI decision
// Log AI agent decisions permanently and immutably
_, err := db.Ingest(ctx, "ai_decisions", map[string]any{
"model": "gpt-4o",
"action": "approve_loan",
"confidence": 0.94,
"applicant": "cust_001",
"reasoning": "Credit score 780, DTI 28%",
})
// Every decision is cryptographically signed — you can always prove
// what the AI decided, when, and why.Error Handling
All errors are typed and can be inspected with errors.As.
Go
import "errors"
record, err := db.Collection("orders").Get(ctx, "nuc_missing")
if err != nil {
var notFound *sapixdb.SapixNotFoundError
var netErr *sapixdb.SapixNetworkError
var sapixErr *sapixdb.SapixError
switch {
case errors.As(err, ¬Found):
fmt.Println("not found:", notFound.RecordID)
case errors.As(err, &netErr):
fmt.Println("network error:", netErr.Cause)
case errors.As(err, &sapixErr):
fmt.Printf("error %d: %s\n", sapixErr.Status, sapixErr.Message)
}
}Full Example: Online Store
Go — main.go
package main
import (
"context"
"fmt"
"time"
sapixdb "github.com/sapixdb/sapixdb-go"
)
func main() {
ctx := context.Background()
db := sapixdb.New(sapixdb.Config{
URL: "http://localhost:7475",
Agent: "store",
})
// 1. Add product
shirt, _ := db.Collection("products").Write(ctx, map[string]any{
"sku": "SHIRT-001", "name": "Classic T-Shirt",
"price": 29.99, "stock": 200, "category": "apparel",
})
// 2. Register customer
customer, _ := db.Collection("customers").Write(ctx, map[string]any{
"name": "Alice Johnson", "email": "[email protected]",
})
// 3. Place order
order, _ := db.Collection("orders").Write(ctx, map[string]any{
"customer_id": customer.ID,
"items": []any{map[string]any{
"product_id": shirt.ID, "qty": 2, "unit_price": 29.99,
}},
"total": 59.98,
"status": "placed",
})
// 4. Link in graph
_ = db.Graph.Relate(ctx, order.ID, customer.ID, "placed_by", 1.0)
_ = db.Graph.Relate(ctx, order.ID, shirt.ID, "contains", 1.0)
// 5. Ship (append — "placed" version is preserved forever)
_, _ = db.Collection("orders").Write(ctx, map[string]any{
"customer_id": customer.ID,
"status": "shipped",
"tracking": "UPS-1Z999AA10123456784",
})
// 6. Audit: what was the status when it was placed?
original, _ := db.Collection("orders").
AsOf(order.Timestamp).
FindOne(ctx, map[string]any{"customer_id": customer.ID})
fmt.Println(original.Data["status"]) // "placed" — not "shipped"
_ = time.Second // import kept for Timeout example
}Also available: JavaScript / TypeScript and Python SDKs
npm install sapixdb and pip install sapixdb — same API, every language.