A comprehensive, production-ready Go utility library that provides common functionality for web applications built with Gin, GORM, and other popular Go frameworks. EZUtil is designed to accelerate development by providing well-tested, reusable components for modern Go web applications.
- Gin Parameter Extraction: Type-safe parameter parsing with
GetPathParam[T],GetQueryParam[T] - Request Binding: Simplified JSON/form data binding with validation
- Response Helpers: Standardized JSON response utilities
- Middleware Support: Common middleware implementations for web applications
- Routing Utilities: Simplified routing helpers and patterns
- GORM Integration: Seamless database connection management and configuration
- Query Scopes: Reusable, composable query scopes for common database operations
- Transaction Management: Robust transaction utilities with nested transaction support
- Multi-Database Support: MySQL and PostgreSQL drivers with automatic configuration
- Connection Pooling: Optimized database connection management
- Environment-Based Config: Automatic configuration loading from environment variables
- Type-Safe Parsing: Built-in validation and type conversion for configuration values
- Database Auto-Configuration: Automatic database connection setup with fallback defaults
- Application Settings: Centralized management of app-level configuration
- Flexible Loading: Support for loading configuration with or without database dependency
- JWT Service: Complete JWT token creation, verification, and management
- Secure Token Handling: Built-in token expiration and refresh capabilities
- Authentication Middleware: Ready-to-use authentication middleware for Gin
- Security Best Practices: Implements industry-standard security patterns
- Type-Safe Parsing: Generic
Parse[T]function for string-to-type conversion - String Utilities: Random string generation, manipulation, and validation
- Time Management: Date/time formatting, manipulation, and timezone handling
- Slice Operations: Functional programming utilities (
MapSlice,MapSliceWithError) - Error Handling: Structured error types with HTTP context and stack traces
- Template Integration: Seamless integration with Templ template engine
- UUID Support: UUID generation, parsing, and validation utilities
go get github.com/itsLeonB/ezutilRequirements:
- Go 1.23 or higher
- Compatible with Go 1.23, and 1.24
package main
import (
"log"
"time"
"github.com/gin-gonic/gin"
"github.com/itsLeonB/ezutil"
)
func main() {
// Load configuration from environment
defaults := ezutil.Config{
App: &ezutil.App{
Env: "development",
Port: "8080",
Timeout: 30 * time.Second,
ClientUrls: []string{"http://localhost:8080"},
Timezone: "UTC",
},
Auth: &ezutil.Auth{
SecretKey: "your-secret-key",
TokenDuration: 24 * time.Hour,
CookieDuration: 7 * 24 * time.Hour,
Issuer: "your-app",
URL: "http://localhost:8080",
},
}
config := ezutil.LoadConfig(defaults)
// Create Gin router
r := gin.Default()
// Use EZUtil helpers for type-safe parameter extraction
r.GET("/user/:id", func(c *gin.Context) {
userID, exists, err := ezutil.GetPathParam[int](c, "id")
if err != nil {
c.JSON(400, gin.H{"error": "Invalid user ID format"})
return
}
if !exists {
c.JSON(400, gin.H{"error": "User ID is required"})
return
}
c.JSON(200, gin.H{"user_id": userID, "message": "User found"})
})
// Start server
log.Printf("Server starting on port %s", config.App.Port)
r.Run(":" + config.App.Port)
}Create a .env file or set environment variables:
# Application Configuration
APP_ENV=production
APP_PORT=8080
APP_TIMEOUT=30s
APP_TIMEZONE=UTC
APP_CLIENTURLS=http://localhost:8080,https://yourdomain.com
# Database Configuration
SQLDB_HOST=localhost
SQLDB_PORT=5432
SQLDB_NAME=myapp
SQLDB_USER=username
SQLDB_PASSWORD=password
SQLDB_DRIVER=postgres
# Authentication Configuration
AUTH_SECRETKEY=your-super-secret-jwt-key
AUTH_TOKENDURATION=24h
AUTH_COOKIEDURATION=168h
AUTH_ISSUER=myapp
AUTH_URL=https://yourdomain.com// Initialize transactor
transactor := ezutil.NewTransactor(db)
// Use transactions with automatic rollback on error
err := transactor.WithinTransaction(ctx, func(ctx context.Context) error {
tx, err := ezutil.GetTxFromContext(ctx)
if err != nil {
return err
}
// Perform database operations within transaction
user := User{Name: "John Doe", Email: "john@example.com"}
if err := tx.Create(&user).Error; err != nil {
return err // Transaction will be rolled back automatically
}
// Nested transactions are supported
return transactor.WithinTransaction(ctx, func(ctx context.Context) error {
innerTx, err := ezutil.GetTxFromContext(ctx)
if err != nil {
return err
}
profile := Profile{UserID: user.ID, Bio: "Software Developer"}
return innerTx.Create(&profile).Error
})
})
if err != nil {
log.Printf("Transaction failed: %v", err)
}// Parse various types from strings
userID, err := ezutil.Parse[int]("123")
if err != nil {
log.Printf("Invalid user ID: %v", err)
}
isActive, err := ezutil.Parse[bool]("true")
price, err := ezutil.Parse[float64]("29.99")
uuid, err := ezutil.Parse[uuid.UUID]("550e8400-e29b-41d4-a716-446655440000")
// Generate secure random strings
apiKey, err := ezutil.GenerateRandomString(32)
if err != nil {
log.Printf("Failed to generate API key: %v", err)
}// Transform slices with type safety
numbers := []int{1, 2, 3, 4, 5}
doubled := ezutil.MapSlice(numbers, func(n int) int {
return n * 2
})
// Result: [2, 4, 6, 8, 10]
// Handle errors during transformation
strings := []string{"1", "2", "invalid", "4"}
numbers, err := ezutil.MapSliceWithError(strings, func(s string) (int, error) {
return ezutil.Parse[int](s)
})
if err != nil {
log.Printf("Conversion failed: %v", err)
}// Create structured application errors
appErr := ezutil.NewAppError(
"VALIDATION_ERROR",
"Invalid input provided",
http.StatusBadRequest,
map[string]string{
"field": "email",
"issue": "invalid format",
},
)
// Use in Gin handlers with automatic error response
r.POST("/users", func(c *gin.Context) {
var user User
if err := c.ShouldBindJSON(&user); err != nil {
ezutil.HandleError(c, ezutil.NewAppError(
"BIND_ERROR",
"Invalid JSON payload",
http.StatusBadRequest,
nil,
))
return
}
// Process user...
})// Create JWT service
jwtService := ezutil.NewJWTService(config.Auth.SecretKey, config.Auth.Issuer)
// Generate tokens
claims := map[string]interface{}{
"user_id": 123,
"role": "admin",
}
token, err := jwtService.GenerateToken(claims, config.Auth.TokenDuration)
if err != nil {
log.Printf("Token generation failed: %v", err)
}
// Verify tokens
parsedClaims, err := jwtService.VerifyToken(token)
if err != nil {
log.Printf("Token verification failed: %v", err)
}ezutil/
├── .github/
│ └── workflows/ # CI/CD workflows
│ ├── ci.yml # Main CI pipeline
│ ├── test.yml # Extended testing with security scans
│ └── lint.yml # Code linting
├── internal/ # Internal utilities
│ └── *_test.go # Internal package tests
├── config_loader.go # Environment configuration loading
├── errors.go # Error handling utilities
├── gin_*.go # Gin framework utilities
├── gorm_*.go # GORM database utilities
├── http_utils.go # HTTP utilities
├── services.go # Service layer utilities (JWT, etc.)
├── slice_utils.go # Slice manipulation utilities
├── sql_utils.go # SQL utilities
├── string_utils.go # String manipulation utilities
├── templ_utils.go # Template utilities
├── time_utils.go # Time/date utilities
├── uuid_utils.go # UUID utilities
├── Makefile # Build and test automation
├── go.mod # Go module definition
└── README.md # This file
EZUtil includes a comprehensive test suite with over 200 individual test cases covering all exported functions and methods. The tests are organized alongside their respective source files using the ezutil_test package for proper isolation.
The test suite provides comprehensive coverage including:
- ✅ All exported functions and methods - 100% coverage of public API
- ✅ Happy path scenarios - Normal operation testing
- ✅ Error conditions - Comprehensive error handling validation
- ✅ Edge cases - Boundary condition testing
- ✅ Database operations - Using in-memory SQLite for isolation
- ✅ HTTP request/response handling - Complete web layer testing
- ✅ JWT token operations - Authentication flow testing
- ✅ Configuration loading - Environment variable processing
- ✅ Transaction management - Database transaction testing
- ✅ Type safety - Generic function validation
Use the provided Makefile commands for various testing scenarios:
# Show all available commands
make help
# Run all tests (quick)
make test
# Run tests with verbose output
make test-verbose
# Run tests with coverage report
make test-coverage
# Generate HTML coverage report
make test-coverage-html
# Clean test cache and run fresh tests
make test-cleanThe project uses GitHub Actions for comprehensive CI/CD:
- Multi-version testing: Go 1.23, 1.24
- Automated testing: Full test suite execution
- Coverage reporting: Automatic upload to Codecov
- Build verification: Cross-version compatibility
- Comprehensive testing: All test scenarios
- Security scanning: Gosec static analysis
- Dependency verification: Module integrity checks
- SARIF reporting: Security findings integration
- Static analysis: golangci-lint integration
- Code formatting: Automated style checking
- Best practices: Go idiom enforcement
Tests are co-located with their respective source files:
├── generic_mappers_test.go # Generic mapper tests
├── slice_utils_test.go # Slice operation tests
├── sql_utils_test.go # SQL utility tests
├── string_utils_test.go # String manipulation tests
├── time_utils_test.go # Time/date utility tests
├── uuid_utils_test.go # UUID utility tests
└── internal/
└── simple_logger_test.go # Internal logger tests
EZUtil builds upon several excellent Go packages:
- Gin
v1.9.1- HTTP web framework - GORM
v1.25.5- ORM library for database operations - Eris
v0.8.1- Error handling and stack traces - JWT
v5.2.0- JSON Web Token implementation
- MySQL Driver - MySQL database support
- PostgreSQL Driver - PostgreSQL database support
- Templ
v0.2.543- Template engine integration - Envconfig
v1.4.0- Environment variable configuration - UUID
v1.4.0- UUID generation and parsing
- Testify
v1.8.4- Testing assertions and mocks - SQLite Driver - In-memory testing database
| Variable | Type | Default | Description |
|---|---|---|---|
APP_ENV |
string | development |
Application environment |
APP_PORT |
string | 3000 |
Server port number |
APP_TIMEOUT |
duration | 10s |
Request timeout |
APP_CLIENTURLS |
[]string | ["http://localhost:3000"] |
Allowed client URLs |
APP_TIMEZONE |
string | America/New_York |
Application timezone |
| Variable | Type | Required | Description |
|---|---|---|---|
SQLDB_HOST |
string | ✅ | Database host |
SQLDB_PORT |
string | ✅ | Database port |
SQLDB_NAME |
string | ✅ | Database name |
SQLDB_USER |
string | ✅ | Database username |
SQLDB_PASSWORD |
string | ✅ | Database password |
SQLDB_DRIVER |
string | ✅ | Database driver (mysql or postgres) |
| Variable | Type | Default | Description |
|---|---|---|---|
AUTH_SECRETKEY |
string | default-secret |
JWT signing key |
AUTH_TOKENDURATION |
duration | 30m |
JWT token lifetime |
AUTH_COOKIEDURATION |
duration | 12h |
Cookie lifetime |
AUTH_ISSUER |
string | default-issuer |
JWT issuer |
AUTH_URL |
string | http://localhost:3000 |
Authentication service URL |
- Connection Pooling: Automatic connection pool management
- Transaction Efficiency: Nested transaction support with proper rollback
- Query Optimization: Reusable scopes for common query patterns
- Type Safety: Compile-time type checking for database operations
- JWT Security: Secure token generation with configurable expiration
- Input Validation: Built-in parameter validation and sanitization
- Error Handling: Structured errors without sensitive information leakage
- HTTPS Support: Ready for production HTTPS deployment
- Type Safety: Generic functions for compile-time type checking
- Error Context: Rich error information with stack traces
- Testing Support: Comprehensive test utilities and mocks
- Documentation: Extensive inline documentation and examples
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
-
Fork and Clone
git clone https://github.com/yourusername/ezutil.git cd ezutil -
Install Dependencies
go mod download cd test && go mod download
-
Run Tests
make test-verbose
-
Run Linting
make lint
- Code Quality: Ensure all tests pass and maintain test coverage
- Documentation: Update documentation for new features
- Commit Messages: Use clear, descriptive commit messages
- Pull Requests: Include description of changes and test results
- Create your feature branch (
git checkout -b feature/amazing-feature) - Make your changes and add tests
- Ensure all tests pass (
make test) - Run linting (
make lint) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Ellion Blessan - itsLeonB
- The Go community for excellent libraries and tools
- Contributors who help improve this project
- Users who provide feedback and bug reports
EZUtil - Making Go web development easier, one utility at a time. 🚀
Built with ❤️ for the Go community