Skip to content

yigithankarabulut/wirekit

wirekit

A slim, fit Go toolkit for common infrastructure components. Wire up your services with sensible defaults and minimal configuration. Designed to be used in codebases with existing packages to avoid conflicts.

Go Reference Go Report Card

Installation

go get github.com/yigithankarabulut/wirekit

Features

  • 🔌 Database Connections: PostgreSQL (GORM, pgx, sql), MongoDB
  • 🗄️ Cache & Messaging: Redis (Client, Cache, PubSub, Queue)
  • 📬 Message Brokers: Kafka, RabbitMQ, MQTT
  • 📝 Logging: Zap-based with context support
  • 🔐 JWT: Token generation and validation
  • Validation: Echo-compatible request validation
  • 🛠️ Utilities: String, Crypto, Time, HTTP client, Retry, Rate limiting

Philosophy

Convention over Configuration - sensible defaults that just work, with full customization available when needed.

Examples

Check out the example/ directory for complete, runnable examples:

Example Description
basic Logging, strings, crypto, time, email utilities
http-client HTTP client with retries and JSON handling
retry Retry logic with backoff strategies
jwt JWT token generation and validation
validation Request validation with custom rules
ratelimit Token bucket and sliding window rate limiting
response API response formatting and pagination
database PostgreSQL and MongoDB connections
cache Redis client, cache, pub/sub, queue

Quick Start

package main

import (
    "context"
    "os"

    "github.com/yigithankarabulut/wirekit"
    "go.uber.org/zap"
)

func main() {
    ctx := context.Background()

    // Initialize logging
    wirekit.Log(wirekit.Zap).
        WithLevel("debug").
        Init()

    // Connect to PostgreSQL
    db, err := wirekit.Postgres().
        GORM().
        WithDSN(os.Getenv("DATABASE_URL")).
        Connect()
    if err != nil {
        wirekit.Fatal("failed to connect to postgres", zap.Error(err))
    }

    // Connect to Redis
    cache, err := wirekit.Redis().
        Cache().
        WithAddr("localhost:6379").
        Connect(ctx)
    if err != nil {
        wirekit.Fatal("failed to connect to redis", zap.Error(err))
    }
    defer cache.Close()

    wirekit.Info("services connected successfully")
}

Usage Examples

Logging

// Initialize with defaults
wirekit.Log(wirekit.Zap).Init()

// Or customize
wirekit.Log(wirekit.Zap).
    WithLevel("debug").
    WithContextFields(func(ctx context.Context) []zap.Field {
        return []zap.Field{
            zap.String("user_id", wirekit.Ctx.UserID(ctx)),
            zap.String("trace_id", wirekit.Ctx.TraceID(ctx)),
        }
    }).
    Init()

// Use global functions
wirekit.Info("server started", zap.String("port", "8080"))
wirekit.ErrorCtx(ctx, "request failed", zap.Error(err))

PostgreSQL

// GORM
db, err := wirekit.Postgres().
    GORM().
    WithDSN("postgres://user:pass@localhost:5432/db").
    WithMaxOpenConns(50).      // default: 100
    WithMaxIdleConns(10).      // default: 10
    Connect()

// pgx (high-performance)
pool, err := wirekit.Postgres().
    PGX().
    WithDSN("postgres://user:pass@localhost:5432/db").
    Connect(ctx)

// database/sql
db, err := wirekit.Postgres().
    SQL().
    WithDSN("postgres://user:pass@localhost:5432/db").
    Connect()

Redis

// Raw client
client, err := wirekit.Redis().
    Client().
    WithAddr("localhost:6379").
    Connect(ctx)

// Cache interface
cache, err := wirekit.Redis().
    Cache().
    WithAddr("localhost:6379").
    WithDefaultTTL(5 * time.Minute).
    Connect(ctx)

cache.Set(ctx, "key", "value", 0)
cache.SetJSON(ctx, "user:123", user, time.Hour)
cache.GetJSON(ctx, "user:123", &user)

// Pub/Sub
pubsub, err := wirekit.Redis().
    PubSub().
    WithAddr("localhost:6379").
    Connect(ctx)

pubsub.Publish(ctx, "events", message)
ch, _ := pubsub.Subscribe(ctx, "events")

// Queue
queue, err := wirekit.Redis().
    Queue().
    WithAddr("localhost:6379").
    Connect(ctx)

queue.Push(ctx, "jobs", jobData)
job, _ := queue.Pop(ctx, "jobs", 30*time.Second)

MongoDB

client, err := wirekit.Mongo().
    WithURI("mongodb://localhost:27017").
    Connect(ctx)

// Or with database
client, db, err := wirekit.Mongo().
    WithURI("mongodb://localhost:27017").
    WithDatabase("myapp").
    ConnectWithDB(ctx)

Kafka

// Producer
producer, err := wirekit.Kafka().
    Producer().
    WithBrokers([]string{"localhost:9092"}).
    WithTopic("events").
    Connect()

producer.Write(ctx, []byte("key"), []byte("value"))

// Consumer
consumer, err := wirekit.Kafka().
    Consumer().
    WithBrokers([]string{"localhost:9092"}).
    WithTopic("events").
    WithGroupID("my-group").
    Connect(ctx)

msg, _ := consumer.Read(ctx)

RabbitMQ

// Publisher
pub, err := wirekit.RabbitMQ().
    Publisher().
    WithURL("amqp://localhost:5672").
    Connect()

pub.Publish(ctx, "", "queue-name", []byte("message"))

// Subscriber
sub, err := wirekit.RabbitMQ().
    Subscriber().
    WithURL("amqp://localhost:5672").
    WithQueue("queue-name").
    Connect()

msgs, _ := sub.Consume()
for msg := range msgs {
    // process message
    sub.Ack(msg, false)
}

MQTT

mqtt, err := wirekit.MQTT().
    WithBroker("tcp://localhost:1883").
    WithClientID("my-service").
    Connect()

mqtt.Publish("topic", payload, 0, false)
mqtt.Subscribe("topic", 0, func(topic string, payload []byte) {
    // handle message
})

JWT

// Generate
token, err := wirekit.JWT().
    WithSecret("my-secret-key").
    WithExpiration(24 * time.Hour).
    WithClaim("role", "admin").
    Generate("user-123")

// Validate
claims, err := wirekit.JWT().
    WithSecret("my-secret-key").
    Validate(token)

userID := claims.Subject()
role := claims.GetString("role")

HTTP Client

client := wirekit.HTTP().
    WithBaseURL("https://api.example.com").
    WithTimeout(10 * time.Second).
    WithBearerToken("xxx").
    WithRetry(3, time.Second).
    Build()

resp, _ := client.Get(ctx, "/users")
var user User
client.GetJSON(ctx, "/users/1", &user)

Validation (Echo)

import "github.com/labstack/echo/v4"

e := echo.New()
e.Validator = wirekit.Validator(wirekit.Echo).
    WithRule("slug", validation.Slug).
    WithRule("strong_password", validation.StrongPassword).
    Build()

// In handler
var req CreateUserRequest
if err := wirekit.BindAndValidate(c, &req); err != nil {
    return c.JSON(400, wirekit.Response.BadRequest(err.Error()))
}

Response Presenter

wirekit.Response.Success(data)
wirekit.Response.SuccessMessage("Created!")
wirekit.Response.Fail(err)
wirekit.Response.BadRequest("invalid input")
wirekit.Response.NotFound("user not found")
wirekit.Response.Paginated(items, page, perPage, total)

Retry

err := wirekit.Retry().
    WithAttempts(5).
    WithDelay(time.Second).
    WithBackoff(retry.ExponentialBackoff).
    Do(ctx, func() error {
        return someOperation()
    })

Rate Limiting

limiter := wirekit.RateLimit().
    WithRate(100, time.Minute).
    InMemory()

allowed, remaining, resetAt := limiter.Allow(ctx, "user:123")

Utility Packages

// String utilities
wirekit.Str.Slugify("Hello World")        // "hello-world"
wirekit.Str.RandomString(16)              // random hex string
wirekit.Str.Mask("1234567890", 2, 2)      // "12******90"

// Crypto utilities
hash, _ := wirekit.Crypto.HashPassword("secret")
ok := wirekit.Crypto.CheckPassword("secret", hash)
wirekit.Crypto.SHA256("data")
wirekit.Crypto.UUID()

// Time utilities
wirekit.Time.StartOfDay(time.Now())
wirekit.Time.AddBusinessDays(time.Now(), 5)
wirekit.Time.HumanSince(createdAt)        // "2 hours ago"

// Context utilities
ctx = wirekit.Ctx.SetUserID(ctx, "123")
userID := wirekit.Ctx.UserID(ctx)

// Type conversions
wirekit.Conv.ToInt("123")
wirekit.Conv.ToIntOr("abc", 0)
wirekit.Conv.StructToMap(myStruct)

// MongoDB helpers
wirekit.MongoX.ToObjectID("507f1f77bcf86cd799439011")
wirekit.MongoX.IsValidObjectID("...")

// Email utilities
wirekit.Email.IsValid("test@example.com")
wirekit.Email.IsDisposable("test@tempmail.com")
wirekit.Email.Mask("test@example.com")    // "t***@example.com"

Defaults

Package Option Default
PostgreSQL MaxOpenConns 100
MaxIdleConns 10
ConnMaxLifetime 10 min
MongoDB Timeout 10s
MaxPoolSize 100
Redis DB 0
PoolSize 10
Kafka BatchSize 100
MQTT AutoReconnect true
KeepAlive 30s
JWT Expiration 1 hour
HTTP Client Timeout 30s
Retry Attempts 3
Backoff Exponential

License

MIT License - see LICENSE for details.

About

Simple and useful Go toolset for common infrastructure components. Being developed.

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Sponsor this project

Packages

 
 
 

Contributors

Languages