Thanks to visit codestin.com
Credit goes to github.com

Skip to content
/ idiogo Public template

A production-ready Go template combining idiomatic Go practices with DDD architecture patterns

License

Notifications You must be signed in to change notification settings

salihguru/idiogo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

idiogo

Idiomatic Go + Domain-Driven Design - A production-ready Go template combining idiomatic Go practices with DDD architecture patterns.

Go Version License

πŸ“‹ Table of Contents

🎯 Overview

idiogo is a modern, production-ready Go boilerplate that combines idiomatic Go practices with Domain-Driven Design (DDD) principles. It provides a solid foundation for building scalable, maintainable REST APIs with clean architecture.

This template is designed to help you kickstart Go projects with best practices baked in, including:

  • Clean DDD architecture
  • Type-safe request/response handling
  • Built-in validation and i18n support
  • Database migrations with GORM
  • Docker-ready deployment
  • Middleware patterns

Useful Links

✨ Features

Core Features

  • πŸ—οΈ Domain-Driven Design: Clean separation of concerns with domain, application, and infrastructure layers
  • πŸš€ Fiber Framework: High-performance HTTP framework built on Fasthttp
  • πŸ—ƒοΈ GORM ORM: Powerful ORM with PostgreSQL support and auto-migrations
  • βœ… Validation: Comprehensive request validation with go-playground/validator
  • 🌍 Internationalization: Multi-language support with go-i18n
  • πŸ”„ Type-Safe Handlers: Generic handler patterns for type-safe request/response handling
  • πŸ“¦ Dependency Injection: Clean dependency management pattern
  • 🐳 Docker Support: Production-ready Docker and Docker Compose configurations

Developer Experience

  • πŸ”§ Hot Reload Ready: Easy integration with development tools
  • πŸ“ Structured Logging: Clean, readable log output
  • 🎯 Graceful Shutdown: Proper resource cleanup on termination
  • πŸ” Security: Built-in security headers and proxy detection
  • πŸ“Š Database Migrations: Automatic schema management with GORM

πŸ›οΈ Architecture

idiogo follows a Layered DDD Architecture with clear separation of concerns:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚            cmd/ (Entry Points)              β”‚
β”‚  β€’ serve: REST API server                   β”‚
β”‚  β€’ cron: Background jobs                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚        internal/app (Application)           β”‚
β”‚  β€’ Application initialization               β”‚
β”‚  β€’ Module composition                       β”‚
β”‚  β€’ Dependency wiring                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚       internal/domain (Business Logic)      β”‚
β”‚  β€’ Entities & Aggregates                    β”‚
β”‚  β€’ Services (Business Logic)                β”‚
β”‚  β€’ Repository Interfaces                    β”‚
β”‚  β€’ Handlers (HTTP)                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚        internal/infra (Infrastructure)      β”‚
β”‚  β€’ Database connections                     β”‚
β”‚  β€’ External service integrations            β”‚
β”‚  β€’ Repository implementations               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          pkg/ (Shared Packages)             β”‚
β”‚  β€’ Reusable utilities                       β”‚
β”‚  β€’ Common types & helpers                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Principles

  1. Domain Layer (internal/domain/): Contains business logic, entities, and domain services
  2. Application Layer (internal/app/): Orchestrates domain logic and handles use cases
  3. Infrastructure Layer (internal/infra/): Technical implementations (DB, external APIs)
  4. Interface Layer (internal/rest/, internal/port/): HTTP handlers and protocol adapters
  5. Shared Kernel (pkg/): Reusable utilities and common abstractions

πŸ“ Project Structure

idiogo/
β”œβ”€β”€ cmd/                          # Application entry points
β”‚   β”œβ”€β”€ serve/                    # REST API server
β”‚   β”‚   β”œβ”€β”€ main.go
β”‚   β”‚   └── Dockerfile
β”‚   └── cron/                     # Background jobs
β”‚       └── main.go
β”œβ”€β”€ internal/                     # Private application code
β”‚   β”œβ”€β”€ app/                      # Application layer
β”‚   β”‚   β”œβ”€β”€ serve/               # Server initialization
β”‚   β”‚   └── cron/                # Cron initialization
β”‚   β”œβ”€β”€ domain/                   # Business logic layer
β”‚   β”‚   └── todo/                # Example domain (Todo)
β”‚   β”‚       β”œβ”€β”€ todo.go          # Entity
β”‚   β”‚       β”œβ”€β”€ service.go       # Business logic
β”‚   β”‚       β”œβ”€β”€ repo.go          # Repository implementation
β”‚   β”‚       β”œβ”€β”€ handler.go       # HTTP handlers
β”‚   β”‚       └── filters.go       # Query filters
β”‚   β”œβ”€β”€ infra/                    # Infrastructure layer
β”‚   β”‚   └── db/                  # Database
β”‚   β”‚       β”œβ”€β”€ pg.go            # PostgreSQL connection
β”‚   β”‚       └── migration/       # DB migrations
β”‚   β”œβ”€β”€ rest/                     # REST API implementation
β”‚   β”‚   β”œβ”€β”€ rest.go              # Server setup
β”‚   β”‚   β”œβ”€β”€ service.go           # REST service utilities
β”‚   β”‚   β”œβ”€β”€ handler.go           # Generic handlers
β”‚   β”‚   └── middleware/          # HTTP middlewares
β”‚   β”œβ”€β”€ port/                     # Ports (interfaces)
β”‚   β”‚   └── rest.go              # REST port interface
β”‚   └── config/                   # Configuration
β”‚       β”œβ”€β”€ config.go            # Config structures
β”‚       └── bind.go              # Config loader
β”œβ”€β”€ pkg/                          # Public shared packages
β”‚   β”œβ”€β”€ entity/                  # Base entities
β”‚   β”œβ”€β”€ i18np/                   # Internationalization
β”‚   β”œβ”€β”€ validation/              # Validation utilities
β”‚   β”œβ”€β”€ query/                   # Query builders
β”‚   β”œβ”€β”€ state/                   # State management
β”‚   β”œβ”€β”€ list/                    # List/pagination
β”‚   └── server/                  # Server utilities
β”œβ”€β”€ assets/                       # Static assets
β”‚   └── locales/                 # Translation files
β”‚       β”œβ”€β”€ en.toml
β”‚       └── tr.toml
β”œβ”€β”€ deployments/                  # Deployment configurations
β”‚   β”œβ”€β”€ compose.yml              # Docker Compose
β”‚   └── config.yml               # Application config
β”œβ”€β”€ docs/                         # Documentation
β”œβ”€β”€ tmp/                          # Temporary files (gitignored)
β”œβ”€β”€ go.mod                        # Go modules
└── README.md

πŸš€ Getting Started

Prerequisites

  • Go: 1.25.5 or higher
  • Docker: Latest version (for containerized deployment)
  • PostgreSQL: 15+ (or use Docker Compose)

Installation

  1. Clone the repository (or use as a GitHub template):
git clone https://github.com/salihguru/idiogo.git my-project
cd my-project
  1. Install dependencies:
go mod download
  1. Update module name:

Replace github.com/salihguru/idiogo with your module path in:

  • go.mod
  • All import statements
# Use a script or IDE refactoring tools
find . -type f -name "*.go" -exec sed -i '' 's/github.com\/salihguru\/idiogo/your-module-path/g' {} +
  1. Configure the application:

Copy the example configuration:

cp deployments/config.yml config.yaml

Edit config.yaml with your settings.

  1. Start the database:
docker compose -f deployments/compose.yml up -d idiogo-pg
  1. Run migrations (automatic on startup with migrate: true in config)

  2. Start the server:

go run cmd/serve/main.go

The API will be available at http://localhost:4041

βš™οΈ Configuration

Configuration is managed through YAML files. See deployments/config.yml for an example.

Configuration Structure

rest:
  host: 0.0.0.0           # Server host
  port: 4041               # Server port

db:
  host: localhost          # Database host
  port: "5432"             # Database port
  user: idiogo             # Database user
  pass: idiogo             # Database password
  name: idiogo             # Database name
  ssl_mode: disable        # SSL mode (disable, require, verify-ca, verify-full)
  migrate: true            # Auto-run migrations on startup
  debug: false             # Enable SQL query logging

i18n:
  locales:                 # Supported locales
    - en
    - tr
  default: en              # Default locale
  dir: "./assets/locales"  # Locale files directory

Environment Variables

You can override configuration values with environment variables (when implemented):

export DB_HOST=localhost
export DB_PORT=5432
export REST_PORT=8080

πŸ› οΈ Development

Adding a New Domain

  1. Create domain directory:
mkdir -p internal/domain/yourdomein
  1. Define the entity (internal/domain/yourdomain/entity.go):
package yourdomain

import "github.com/salihguru/idiogo/pkg/entity"

type YourEntity struct {
    entity.Base
    Name        string `json:"name"`
    Description string `json:"description"`
}
  1. Create the repository (internal/domain/yourdomain/repo.go):
package yourdomain

import (
    "context"
    "github.com/google/uuid"
    "gorm.io/gorm"
)

type Repo struct {
    db *gorm.DB
}

func NewRepo(db *gorm.DB) *Repo {
    return &Repo{db: db}
}

func (r *Repo) Save(ctx context.Context, entity *YourEntity) error {
    return r.db.WithContext(ctx).Save(entity).Error
}

func (r *Repo) View(ctx context.Context, id uuid.UUID) (*YourEntity, error) {
    var entity YourEntity
    err := r.db.WithContext(ctx).First(&entity, "id = ?", id).Error
    return &entity, err
}
  1. Implement the service (internal/domain/yourdomain/service.go):
package yourdomain

import "context"

type Service struct {
    repo *Repo
}

func NewService(repo *Repo) *Service {
    return &Service{repo: repo}
}

func (s *Service) Create(ctx context.Context, req CreateReq) (*YourEntity, error) {
    entity := &YourEntity{
        Name:        req.Name,
        Description: req.Description,
    }
    if err := s.repo.Save(ctx, entity); err != nil {
        return nil, err
    }
    return entity, nil
}
  1. Create HTTP handlers (internal/domain/yourdomain/handler.go):
package yourdomain

import (
    "github.com/gofiber/fiber/v2"
    "github.com/salihguru/idiogo/internal/port"
    "github.com/salihguru/idiogo/internal/rest"
)

type Handler struct {
    srv Service
}

func NewHandler(srv Service) *Handler {
    return &Handler{srv: srv}
}

func (h *Handler) RegisterRoutes(srv port.RestService, router fiber.Router) {
    group := router.Group("/yourdomains")
    
    group.Post("/",
        srv.Timeout(rest.Handle(rest.WithBody(rest.WithValidation(srv.ValidateStruct(),
            rest.CreateResponds(h.srv.Create))))))
}
  1. Register the module in internal/app/serve/modules.go:
yourDomainRepo := yourdomain.NewRepo(d.DB)
yourDomainService := yourdomain.NewService(yourDomainRepo)
yourdomainModule := rest.Module[*yourdomain.Repo, *yourdomain.Service]{
    Repo:    yourDomainRepo,
    Service: yourDomainService,
    Router:  yourdomain.NewHandler(*yourdomainModule.Service),
}

Running Tests

# Run all tests
go test ./...

# Run tests with coverage
go test -cover ./...

# Run tests for specific package
go test ./internal/domain/todo/...

Code Quality

# Format code
go fmt ./...

# Lint code
golangci-lint run

# Security scan
gosec ./...

πŸ“š API Documentation

Example: Todo API

Create Todo

POST /todos
Content-Type: application/json

{
  "title": "Buy groceries",
  "description": "Milk, eggs, bread"
}

Response:

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "title": "Buy groceries",
  "description": "Milk, eggs, bread",
  "status": "pending",
  "created_at": "2025-12-18T10:00:00Z"
}

List Todos

GET /todos?page=1&limit=10&status=pending

Get Todo

GET /todos/{id}

Update Todo

PATCH /todos/{id}
Content-Type: application/json

{
  "title": "Buy groceries and fruits",
  "status": "completed"
}

Delete Todo

DELETE /todos/{id}

Response Format

All API responses follow a consistent format:

Success Response:

{
  "data": { /* response data */ }
}

Error Response:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": [
      {
        "field": "title",
        "message": "title is required"
      }
    ]
  }
}

πŸ§ͺ Testing

The project includes examples for:

  • Unit tests
  • Integration tests
  • Repository tests

Example test structure:

func TestService_Create(t *testing.T) {
    // Setup
    db := setupTestDB(t)
    repo := NewRepo(db)
    service := NewService(repo)
    
    // Test
    result, err := service.Create(context.Background(), CreateReq{
        Title: "Test Todo",
    })
    
    // Assert
    assert.NoError(t, err)
    assert.NotNil(t, result)
    assert.Equal(t, "Test Todo", result.Title)
}

🐳 Deployment

Docker Compose (Recommended for Development)

# Start all services
docker compose -f deployments/compose.yml up -d

# View logs
docker compose -f deployments/compose.yml logs -f

# Stop services
docker compose -f deployments/compose.yml down

Docker Build

# Build image
docker build -f cmd/serve/Dockerfile -t idiogo:latest .

# Run container
docker run -p 4041:4041 \
  -e DB_HOST=postgres \
  -e DB_PORT=5432 \
  idiogo:latest

Production Deployment

For production deployment:

  1. Set environment-specific configuration
  2. Use secrets management for sensitive data
  3. Enable SSL/TLS for database connections
  4. Configure reverse proxy (nginx, traefik)
  5. Set up monitoring and logging
  6. Enable health checks

Example production config:

rest:
  host: 0.0.0.0
  port: 4041

db:
  host: ${DB_HOST}
  port: ${DB_PORT}
  user: ${DB_USER}
  pass: ${DB_PASSWORD}
  name: ${DB_NAME}
  ssl_mode: require
  migrate: false
  debug: false

i18n:
  locales: [en, tr]
  default: en
  dir: "/app/assets/locales"

🀝 Contributing

Contributions are welcome! Please read CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.

Development Workflow

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Run tests (go test ./...)
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

πŸ“„ License

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

πŸ™ Acknowledgments

πŸ“ž Support


Built with ❀️ using idiomatic Go and DDD principles

About

A production-ready Go template combining idiomatic Go practices with DDD architecture patterns

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

 

Packages

No packages published