contrib/

directory
v1.3.0 Latest Latest
Warning

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

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

README ΒΆ

EchoNext Contrib Packages

Optional helper packages for EchoNext applications. These packages are completely optional - you can use the libraries directly if you prefer, or use these helpers to reduce boilerplate code.

πŸ“¦ Available Packages

1. Database (pkg/contrib/database)

GORM integration helpers for database operations.

Features:

  • Connection management with retry logic
  • Generic Repository[T] pattern with CRUD operations
  • Transaction helpers (WithTx, WithTxResult)
  • Migration utilities
  • Connection pool configuration

Example:

import (
    "github.com/abdussamadbello/echonext/pkg/contrib/database"
    "gorm.io/driver/postgres"
)

// Connect to database
cfg := database.DefaultConfig()
cfg.DSN = "postgres://user:pass@localhost/mydb"
db, err := database.Connect(postgres.Open(cfg.DSN), cfg)
if err != nil {
    log.Fatal(err)
}

// Use repository pattern
type User struct {
    ID    uint   `gorm:"primaryKey"`
    Name  string `gorm:"not null"`
    Email string `gorm:"unique;not null"`
}

userRepo := database.NewRepository[User](db)

// Create
user := &User{Name: "John", Email: "john@example.com"}
err = userRepo.Create(user)

// Find
user, err = userRepo.Find(1)

// Find all with conditions
users, err := userRepo.Where("name LIKE ?", "John%").FindAll()

// Update
user.Name = "John Doe"
err = userRepo.Update(user)

// Delete
err = userRepo.Delete(1)

// Use transactions
err = database.WithTx(db, func(tx *gorm.DB) error {
    repo := userRepo.WithTx(tx)
    return repo.Create(&user)
})

// Auto-migrate
err = database.AutoMigrate(db, &User{})
Atlas Migrations

The database package includes Atlas integration for declarative schema migrations:

import "github.com/abdussamadbello/echonext/pkg/contrib/database"

// Create Atlas instance
atlas := database.NewAtlas(&database.AtlasConfig{
    Dir:        "migrations",
    ConfigFile: "atlas.hcl",
    Env:        "local",
    URL:        os.Getenv("DATABASE_URL"),
})

// Apply migrations
err := atlas.Apply(ctx)

// Check migration status
status, err := atlas.Status(ctx)

// Generate migration from schema diff
output, err := atlas.Diff(ctx, "add_email_column")

// Rollback last migration
err = atlas.Down(ctx)

// Lint migrations for issues
err = atlas.Lint(ctx)

// Check if Atlas CLI is installed
if !database.IsAtlasInstalled() {
    fmt.Println(database.InstallAtlas())
}

CLI Commands:

# Initialize Atlas setup
echonext db init

# Apply migrations
echonext db migrate
echonext db migrate --dry-run
echonext db migrate --env=production

# Check status
echonext db migrate:status

# Generate migration from schema.hcl
echonext db migrate:diff add_users_table

# Create empty migration
echonext db migrate:new custom_migration

# Rollback
echonext db migrate:down --count=1

# Lint migrations
echonext db migrate:lint

# Inspect database schema
echonext db schema:inspect
2. Config (pkg/contrib/config)

Viper integration helpers for configuration management.

Features:

  • Generic config loading with Load[T]
  • Environment variable binding
  • Hot reload with Watch[T]
  • Standard config structures (AppConfig, DatabaseConfig, etc.)
  • Multiple config file formats (YAML, JSON, TOML)

Example:

import "github.com/abdussamadbello/echonext/pkg/contrib/config"

// Define your config structure using standard types
type MyConfig struct {
    App      config.AppConfig      `mapstructure:"app"`
    Database config.DatabaseConfig `mapstructure:"database"`
    Cache    config.CacheConfig    `mapstructure:"cache"`
    Logger   config.LoggerConfig   `mapstructure:"logger"`
}

// Load from file
var cfg MyConfig
if err := config.LoadSimple(&cfg); err != nil {
    log.Fatal(err)
}

// Load with environment variable prefix
// Environment variables: MYAPP_APP_PORT, MYAPP_DATABASE_DSN, etc.
if err := config.LoadWithEnv(&cfg, "MYAPP"); err != nil {
    log.Fatal(err)
}

// Load from specific file
if err := config.LoadFromFile(&cfg, "./config.yaml"); err != nil {
    log.Fatal(err)
}

// Watch for changes
watcher, err := config.Watch(&cfg, config.DefaultLoadOptions(), func(updated *MyConfig) {
    log.Println("Config reloaded!")
    // Update your services with new config
})

Config file example (config.yaml):

app:
  name: "myapp"
  version: "1.0.0"
  environment: "development"
  port: 8080
  debug: true

database:
  driver: "postgres"
  dsn: "postgres://user:pass@localhost/mydb?sslmode=disable"
  auto_migrate: true
  log_queries: true

cache:
  driver: "redis"
  address: "localhost:6379"
  default_ttl: 3600

logger:
  level: "info"
  format: "json"
  output: "stdout"
3. Testing (pkg/contrib/testing)

Testing utilities for EchoNext applications.

Features:

  • APIClient for testing HTTP endpoints
  • FixtureManager for managing test data
  • Factory pattern for creating test entities
  • Suite base class with setup/teardown
  • IntegrationSuite with transaction rollback

Example:

import (
    "testing"
    "github.com/abdussamadbello/echonext"
    echonexttest "github.com/abdussamadbello/echonext/pkg/contrib/testing"
)

func TestUserAPI(t *testing.T) {
    app := echonext.New()
    // Register your routes...

    client := echonexttest.NewAPIClient(app)

    // Test GET request
    resp := client.GET("/users/1")
    resp.AssertStatus(t, 200)

    var user User
    if err := resp.JSON(&user); err != nil {
        t.Fatal(err)
    }

    // Test POST request
    newUser := CreateUserRequest{Name: "John", Email: "john@example.com"}
    resp = client.POST("/users", newUser)
    resp.AssertStatus(t, 201).AssertSuccess(t)

    // Test with authentication
    resp = client.WithAuth("token123").GET("/protected")
    resp.AssertStatus(t, 200)
}

func TestWithFixtures(t *testing.T) {
    fixtures := echonexttest.NewFixtureManager(db)
    defer fixtures.Clear()

    // Load test data
    fixtures.Load(
        &User{ID: 1, Name: "Alice", Email: "alice@example.com"},
        &User{ID: 2, Name: "Bob", Email: "bob@example.com"},
    )

    // Run your tests...
}

func TestWithSuite(t *testing.T) {
    suite := echonexttest.NewSuite(app, db)

    // Load fixtures
    suite.LoadFixtures(
        &User{Name: "Test User", Email: "test@example.com"},
    )

    // Test with suite client
    resp := suite.Client.GET("/users")
    resp.AssertStatus(t, 200)

    // Assert database state
    suite.AssertRecordExists(t, &User{}, "email = ?", "test@example.com")
    suite.AssertRecordCount(t, &User{}, 1)

    // Cleanup happens automatically
}

func TestFactory(t *testing.T) {
    // Create a factory for generating test users
    userFactory := echonexttest.NewFactory(db, func() User {
        return User{
            Name:  "Test User",
            Email: fmt.Sprintf("user%d@example.com", rand.Int()),
        }
    })

    // Create single user
    user, err := userFactory.Create()

    // Create multiple users
    users, err := userFactory.CreateMany(10)
}

🎯 Philosophy

The contrib packages follow these principles:

  1. Completely Optional - You can use the underlying libraries directly
  2. Zero Lock-in - No vendor lock-in, use what you need
  3. Type-Safe - Leverage Go generics for type safety
  4. Minimal Overhead - Thin wrappers that don't hide complexity
  5. Best Practices - Encourage good patterns without forcing them

πŸ“¦ Installation

These packages are part of the EchoNext repository:

go get github.com/abdussamadbello/echonext

Then import what you need:

import (
    "github.com/abdussamadbello/echonext"
    "github.com/abdussamadbello/echonext/pkg/contrib/database"
    "github.com/abdussamadbello/echonext/pkg/contrib/config"
    echonexttest "github.com/abdussamadbello/echonext/pkg/contrib/testing"
)

πŸ”§ Requirements

Each package has its own dependencies:

Database:

  • gorm.io/gorm
  • Database driver (e.g., gorm.io/driver/postgres)
  • Atlas CLI (optional, for migrations)

Config:

  • github.com/spf13/viper
  • github.com/fsnotify/fsnotify

Testing:

  • github.com/abdussamadbello/echonext
  • gorm.io/gorm (optional, for database testing)

πŸ§ͺ Testing

Run tests for all contrib packages:

go test ./pkg/contrib/...

Run tests for a specific package:

go test ./pkg/contrib/database
go test ./pkg/contrib/config
go test ./pkg/contrib/testing

πŸ“ License

Same as EchoNext core - MIT License

Directories ΒΆ

Path Synopsis
Package config provides optional Viper integration helpers for EchoNext applications.
Package config provides optional Viper integration helpers for EchoNext applications.
Package database provides optional GORM integration helpers for EchoNext applications.
Package database provides optional GORM integration helpers for EchoNext applications.
Package middleware provides optional Echo middleware helpers for EchoNext applications.
Package middleware provides optional Echo middleware helpers for EchoNext applications.
Package testing provides optional testing utilities for EchoNext applications.
Package testing provides optional testing utilities for EchoNext applications.

Jump to

Keyboard shortcuts

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