A Go toolkit for building production-grade services. Provides the common infrastructure code you need so you can focus on business logic.
Think of mesh as the foundation beneath your application. It handles the undifferentiated heavy lifting—the stuff every service needs but nobody enjoys writing:
- Database connections with pooling, transactions, and query helpers
- Error handling that maps to HTTP/gRPC status codes automatically
- Resilient HTTP clients with circuit breakers and retry logic
- Redis caching with built-in metrics, cache-aside pattern, and stampede protection
- In-memory caching for fast local access
- Distributed rate limiting with sliding window algorithm (per-IP, per-user)
- Structured logging for development (pretty terminal) and production (JSON)
- Configuration from YAML files with environment variable overrides
You're building a service. You need a database, caching, some HTTP clients, and observability. You could:
- Write all this yourself (time-consuming, easy to get wrong)
- Use a full framework (adds a lot of baggage you might not need)
- Use mesh (lean, composable, you pick what you need)
Mesh is deliberately small and focused. Import only what you need. The packages are independent—no giant dependency tree to drag in.
go get github.com/azghr/meshpackage main
import (
"context"
"time"
"github.com/azghr/mesh/config"
"github.com/azghr/mesh/database"
"github.com/azghr/mesh/cache"
"github.com/azghr/mesh/logger"
"github.com/azghr/mesh/http"
"github.com/azghr/mesh/redis"
)
func main() {
// Load configuration from YAML + environment variables
cfg, err := config.Load("config.yaml", config.WithDefaultConfig())
if err != nil {
log.Fatal(err)
}
// Structured logging
log := logger.New("my-service", "debug", false)
log.Info("service starting", "port", cfg.Server.Port)
// Database connection pool
pool, err := database.NewPool(database.Config{
Host: cfg.Database.Host,
Port: cfg.Database.PortInt,
User: cfg.Database.User,
Password: cfg.Database.Password,
Name: cfg.Database.Name,
MaxOpenConns: 25,
})
if err != nil {
log.Fatal("database connection failed", "error", err)
}
defer pool.Close()
// Redis client
redisClient, err := redis.NewClient(redis.Config{
Host: cfg.Redis.Host,
Port: cfg.Redis.Port,
})
if err != nil {
log.Fatal("redis connection failed", "error", err)
}
defer redisClient.Close()
// Cache layer
myCache, _ := cache.New(redisClient.Client(), 5*time.Minute)
// Resilient HTTP client with circuit breaker + retry
client := http.NewResilientClient(http.DefaultResilientClientConfig("external-api"))
// Use them...
var user User
err = myCache.GetOrSet(ctx, "user:123", &user, time.Hour, func() (any, error) {
return findUser(ctx, pool.DB(), "123")
})
}| Package | Purpose | Docs |
|---|---|---|
config |
YAML config + env overrides | config.md |
database |
PostgreSQL pool + queries | database.md |
errors |
Structured errors → HTTP/gRPC | errors.md |
logger |
Structured logging | logger.md |
json |
Fast JSON serialization | json.md |
| Package | Purpose | Docs |
|---|---|---|
cache |
Redis caching + metrics | cache.md |
memorycache |
In-memory LRU cache | memorycache.md |
| Package | Purpose | Docs |
|---|---|---|
http |
Circuit breaker + retry | http.md |
redis |
Redis client | redis.md |
health |
Health checks | health.md |
ratelimiter |
Rate limiting | ratelimiter.md |
apiversion |
API versioning | apiversion.md |
| Package | Purpose | Docs |
|---|---|---|
queue |
In-memory job queue | queue.md |
taskqueue |
Redis-based queue | taskqueue.md |
workerpool |
Goroutine pool | workerpool.md |
cron |
Cron scheduler | cron.md |
| Package | Purpose | Docs |
|---|---|---|
paginator |
HTTP pagination | paginator.md |
response |
HTTP responses | response.md |
retry |
Retry logic | retry.md |
bulkops |
Bulk DB operations | bulkops.md |
testing |
Test helpers | testing.md |
idgen |
Snowflake IDs | idgen.md |
| Package | Purpose | Docs |
|---|---|---|
auth |
JWT + RBAC | auth.md |
middleware |
HTTP middleware | middleware.md |
telemetry |
Metrics + tracing | telemetry.md |
lock |
Distributed locks | lock.md |
shutdown |
Graceful shutdown | shutdown.md |
eventbus |
Pub/sub events | eventbus.md |
Prevents cascading failures when downstream services are down. Automatically stops calling a failing service until it recovers.
cb := http.NewCircuitBreaker(nil)
err := cb.Execute(func() error {
return callExternalService()
})
if err != nil {
// Service is unavailable, don't even try
}Check cache first, fetch from database on miss, store in cache.
var user User
err := cache.GetOrSet(ctx, "user:"+id, &user, time.Hour, func() (any, error) {
return db.FindUser(ctx, id)
})For fast local caching without Redis:
localCache := memorycache.New(
memorycache.WithMaxSize(1000),
memorycache.WithTTL(5*time.Minute),
)
val, _ := localCache.GetOrSet(ctx, "config:123", func() (any, error) {
return db.GetConfig(ctx, "123")
}, time.Minute)Standardized list pagination:
params, _ := paginator.FromRequest(r, 20)
users, _ := db.ListUsers(ctx, params.Offset(), params.Limit())
total, _ := db.CountUsers(ctx)
response.SuccessWithMeta(w, users, total, params.Page(), params.Limit())Return structured errors that automatically map to HTTP status codes.
// In handlers
if user == nil {
return errors.NotFoundError("user", id)
}
// Maps to HTTP 404 automatically
http.Status = err.ToHTTPStatus()Batch database operations efficiently:
err := bulkops.Insert(ctx, users, 100, func(batch []User) error {
return db.InsertUsers(ctx, batch)
})Lightweight async tasks:
q := queue.New(queue.WithWorkers(4))
q.Enqueue(ctx, queue.Job{Type: "email", Payload: data})
worker := q.Worker("email")
worker.Start(ctx, func(ctx context.Context, job queue.Job) error {
return sendEmail(ctx, job.Payload)
})YAML base with environment variable overrides:
server:
host: 0.0.0.0
port: 8080
environment: development
database:
host: localhost
port: 5432
user: app
name: myapp
ssl_mode: disable
redis:
host: localhost
port: 6379
log:
level: info
json_format: falseOverride with environment variables: DB_HOST, DB_PORT, DB_NAME, REDIS_HOST, etc.
mesh/
├── cache/ # Redis caching
├── memorycache/ # In-memory LRU cache
├── config/ # Configuration + feature flags
├── database/ # PostgreSQL utilities
├── errors/ # Structured errors
├── logger/ # Structured logging
├── json/ # Fast JSON
├── http/ # Circuit breaker + retry
├── redis/ # Redis client
├── health/ # Health checks
├── ratelimiter/ # Rate limiting
├── apiversion/ # API versioning
├── queue/ # In-memory queue
├── taskqueue/ # Redis queue
├── workerpool/ # Goroutine pool
├── cron/ # Cron scheduler
├── middleware/ # HTTP middleware
├── auth/ # JWT + RBAC
├── telemetry/ # Metrics + tracing
├── lock/ # Distributed locks
├── shutdown/ # Graceful shutdown
├── eventbus/ # Pub/sub events
├── paginator/ # Pagination
├── response/ # HTTP responses
├── retry/ # Retry logic
├── bulkops/ # Bulk DB operations
├── testing/ # Test helpers
├── idgen/ # Snowflake IDs
└── ...
go test ./...MIT