go-shared

module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 26, 2025 License: MIT

README ΒΆ

SaaS Shared Go Library

Go Version Go Report Card

A comprehensive collection of reusable Go packages for building multi-tenant SaaS applications. This library provides essential building blocks including authentication, authorization, context management, middleware, database utilities, and more.

Installation

go get github.com/vhvplatform/go-shared@latest

Quick Start

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/vhvplatform/go-shared/middleware"
    "github.com/vhvplatform/go-shared/response"
    "github.com/vhvplatform/go-shared/tenant"
)

func main() {
    router := gin.Default()
    
    // Setup tenant resolver
    tenantResolver := tenant.NewResolver(tenant.ResolverConfig{
        Strategies: []tenant.ResolutionStrategy{
            tenant.StrategyHeader,
            tenant.StrategySubdomain,
        },
    })
    
    // Apply middleware
    router.Use(middleware.ContextMiddleware())
    router.Use(tenantResolver.Middleware())
    
    router.GET("/hello", func(c *gin.Context) {
        response.Success(c, map[string]string{"message": "Hello, World!"})
    })
    
    router.Run(":8080")
}

Features

  • πŸ” Authentication & Authorization - JWT-based auth with permission and role management
  • 🏒 Multi-Tenancy - Flexible tenant resolution strategies (header, subdomain, domain)
  • πŸ“ Context Management - Request-scoped data with correlation ID tracking
  • πŸ”Œ Middleware Collection - Ready-to-use Gin middleware for common tasks
  • πŸ—„οΈ Database Utilities - MongoDB helpers with tenant isolation and transactions
  • πŸ’Ύ Caching - Redis client with multi-tenant support and common patterns
  • πŸ“¨ Messaging - RabbitMQ integration
  • πŸ“Š Structured Logging - Zap-based logger with context support
  • βœ… Validation - Request validation utilities
  • πŸ”„ HTTP Client - Configurable HTTP client with retry and timeout
  • πŸ“¦ Standard Responses - Consistent JSON API responses

This library contains reusable packages that are shared across all microservices in the SaaS framework.

Packages

1. context - Request Context Management

Provides context management for handling request-scoped data across the application.

Features:

  • Store and retrieve user information (ID, email, tenant ID)
  • Manage roles and permissions
  • Track correlation IDs for distributed tracing
  • Tenant domain resolution
  • Integration with Gin framework

Example Usage:

import (
    pkgctx "github.com/vhvplatform/go-shared/context"
)

// Create a request context
rc := &pkgctx.RequestContext{
    UserID:   "user123",
    TenantID: "tenant456",
    Email:    "user@example.com",
    Roles:    []string{"admin"},
}

// Store in standard context
ctx := pkgctx.WithRequestContext(context.Background(), rc)

// Store in Gin context
pkgctx.ToGinContext(c, rc)

// Retrieve values
userID, err := pkgctx.GetUserID(ctx)
tenantID, err := pkgctx.GetTenantID(ctx)
2. auth - Authentication & Authorization Helpers

Provides utilities for checking permissions and roles, and retrieving current user information.

Features:

  • Permission checking with wildcard support (users.*)
  • Role-based access control
  • User information retrieval
  • Global permission checker instance

Example Usage:

import (
    "github.com/vhvplatform/go-shared/auth"
)

// Check permissions
if auth.HasPermission(ctx, "users.read") {
    // Allow access
}

// Require permission (returns error)
if err := auth.RequirePermission(ctx, "users.write"); err != nil {
    // Permission denied
}

// Check roles
if auth.IsSuperAdmin(ctx) {
    // Super admin access
}

// Get current user
user, err := auth.GetCurrentUser(ctx)
3. tenant - Tenant Resolution

Provides multi-strategy tenant resolution from HTTP requests.

Supported Strategies:

  • StrategyHeader - Extract tenant from HTTP header (default: X-Tenant-ID)
  • StrategySubdomain - Extract tenant from subdomain (e.g., tenant.example.com)
  • StrategyDomain - Extract tenant from custom domain
  • StrategyParam - Extract tenant from query/URL parameter

Example Usage:

import (
    "github.com/vhvplatform/go-shared/tenant"
)

// Create resolver with multiple strategies
resolver := tenant.NewResolver(tenant.ResolverConfig{
    Strategies: []tenant.ResolutionStrategy{
        tenant.StrategyHeader,
        tenant.StrategySubdomain,
    },
    HeaderName: "X-Tenant-ID",
})

// Use as middleware
router.Use(resolver.Middleware())

// Manual resolution
tenantID, domain, err := resolver.Resolve(c)
4. middleware - Gin Middleware

Provides ready-to-use middleware for common functionalities.

Available Middleware:

  • ContextMiddleware() - Generates correlation IDs
  • AppContextMiddleware() - Extracts application ID
  • RequestContextMiddleware() - Builds full request context
  • RequirePermission(permission) - Requires specific permission
  • RequireAnyPermission(permissions...) - Requires any of the permissions
  • RequireRole(role) - Requires specific role
  • RequireSuperAdmin() - Requires super admin role
  • RequireTenantAdmin() - Requires tenant admin role

Example Usage:

import (
    "github.com/vhvplatform/go-shared/middleware"
)

// Setup middleware chain
router.Use(middleware.ContextMiddleware())
router.Use(middleware.AppContextMiddleware())

// Protected routes
protected := router.Group("")
protected.Use(AuthMiddleware()) // Your auth middleware
protected.Use(middleware.RequestContextMiddleware())

// Permission-protected endpoint
protected.POST("/users",
    middleware.RequirePermission("users.create"),
    userHandler.CreateUser,
)

// Admin-only endpoint
admin := protected.Group("/admin")
admin.Use(middleware.RequireTenantAdmin())
admin.GET("/settings", settingsHandler.GetSettings)
5. response - Standard API Responses

Provides consistent JSON response formatting across all services.

Features:

  • Success responses with optional metadata
  • Error responses with error codes and details
  • Pagination metadata support
  • Automatic correlation ID inclusion

Example Usage:

import (
    "github.com/vhvplatform/go-shared/response"
)

// Success response
response.Success(c, userData)

// Success with pagination
meta := response.NewMeta(page, perPage, total)
response.SuccessWithMeta(c, users, meta)

// Created response
response.Created(c, newUser)

// Error responses
response.BadRequest(c, "Invalid input")
response.Unauthorized(c, "Authentication required")
response.Forbidden(c, "Insufficient permissions")
response.NotFound(c, "User not found")
response.InternalServerError(c, "Something went wrong")

// Custom error with details
details := map[string]string{"field": "email"}
response.ErrorWithDetails(c, 400, "VALIDATION_ERROR", "Invalid email", details)
Response Format

All responses follow this structure:

Success Response:

{
  "success": true,
  "data": {...},
  "meta": {
    "page": 1,
    "per_page": 10,
    "total": 100,
    "total_pages": 10
  },
  "correlation_id": "uuid"
}

Error Response:

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Error message",
    "details": {...}
  },
  "correlation_id": "uuid"
}

Integration Example

Here's a complete example integrating all packages:

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/vhvplatform/go-shared/auth"
    pkgctx "github.com/vhvplatform/go-shared/context"
    "github.com/vhvplatform/go-shared/middleware"
    "github.com/vhvplatform/go-shared/response"
    "github.com/vhvplatform/go-shared/tenant"
)

func main() {
    router := gin.Default()

    // Setup tenant resolver
    tenantResolver := tenant.NewResolver(tenant.ResolverConfig{
        Strategies: []tenant.ResolutionStrategy{
            tenant.StrategyHeader,
            tenant.StrategySubdomain,
        },
    })

    // Global middleware
    router.Use(middleware.ContextMiddleware())
    router.Use(middleware.AppContextMiddleware())
    router.Use(tenantResolver.Middleware())

    // API routes
    api := router.Group("/api/v1")

    // Protected routes
    protected := api.Group("")
    protected.Use(AuthMiddleware())
    protected.Use(middleware.RequestContextMiddleware())

    // User management
    users := protected.Group("/users")
    users.GET("", middleware.RequirePermission("users.read"), ListUsers)
    users.POST("", middleware.RequirePermission("users.create"), CreateUser)
    users.PUT("/:id", middleware.RequirePermission("users.update"), UpdateUser)
    users.DELETE("/:id", middleware.RequirePermission("users.delete"), DeleteUser)

    // Admin routes
    admin := protected.Group("/admin")
    admin.Use(middleware.RequireTenantAdmin())
    admin.GET("/settings", GetSettings)

    router.Run(":8080")
}

func ListUsers(c *gin.Context) {
    ctx := c.Request.Context()

    // Check authentication
    if !auth.IsAuthenticated(ctx) {
        response.Unauthorized(c, "Authentication required")
        return
    }

    // Get current user info
    currentUser, err := auth.GetCurrentUser(ctx)
    if err != nil {
        response.Unauthorized(c, "Invalid user")
        return
    }

    // Business logic here...
    users := []User{} // Fetch users from DB

    // Return paginated response
    meta := response.NewMeta(1, 10, 100)
    response.SuccessWithMeta(c, users, meta)
}

func CreateUser(c *gin.Context) {
    ctx := c.Request.Context()

    // Get tenant ID
    tenantID, err := auth.GetCurrentTenantID(ctx)
    if err != nil {
        response.BadRequest(c, "Tenant context required")
        return
    }

    // Create user logic...

    response.Created(c, newUser)
}

Testing

Run tests with:

# Test all packages
go test ./...

# Test specific package
go test ./context/
go test ./auth/
go test ./tenant/

# Test with coverage
go test -coverprofile=coverage.txt -covermode=atomic ./...

Versioning

This library follows Semantic Versioning:

  • MAJOR version for incompatible API changes
  • MINOR version for backwards-compatible functionality additions
  • PATCH version for backwards-compatible bug fixes

To use a specific version:

go get github.com/vhvplatform/go-shared@v1.0.0

Dependencies

Key dependencies:

  • github.com/gin-gonic/gin - HTTP web framework
  • github.com/golang-jwt/jwt/v5 - JWT implementation
  • go.mongodb.org/mongo-driver - MongoDB driver
  • github.com/redis/go-redis/v9 - Redis client
  • go.uber.org/zap - Structured logging
  • github.com/spf13/viper - Configuration management

See go.mod for complete dependency list.

Best Practices

  1. Always use context propagation - Pass context through all layers of your application
  2. Check permissions early - Use middleware for route-level checks, helper functions for business logic
  3. Use consistent response format - Always use the response package for API responses
  4. Include correlation IDs - Use ContextMiddleware to track requests across services
  5. Validate tenant context - Always ensure tenant context is available for multi-tenant operations
  6. Test your code - All packages include test examples you can follow

Contributing

See CONTRIBUTING.md for contribution guidelines.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

For issues and questions:

Changelog

See CHANGELOG.md for version history and changes.

Directories ΒΆ

Path Synopsis
Package email provides an abstraction layer for sending emails with support for multiple providers (SMTP, SendGrid, AWS SES, etc.)
Package email provides an abstraction layer for sending emails with support for multiple providers (SMTP, SendGrid, AWS SES, etc.)
Package metrics provides utilities for collecting and exposing application metrics with support for Prometheus and other monitoring systems
Package metrics provides utilities for collecting and exposing application metrics with support for Prometheus and other monitoring systems
Package sms provides an abstraction layer for sending SMS messages with support for multiple providers (Twilio, AWS SNS, Nexmo, etc.)
Package sms provides an abstraction layer for sending SMS messages with support for multiple providers (Twilio, AWS SNS, Nexmo, etc.)
Package storage provides an abstraction layer for object storage with support for multiple providers (S3, MinIO, GCS, Azure Blob, etc.)
Package storage provides an abstraction layer for object storage with support for multiple providers (S3, MinIO, GCS, Azure Blob, etc.)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL