Skip to content
/ goca Public

Goca is a powerful CLI code generator for Go that helps you create Clean Architecture projects following best practices.

License

Notifications You must be signed in to change notification settings

sazardev/goca

Goca - Go Clean Architecture Code Generator

Go Version License Build Status Production Ready GitHub Release Docs

Goca is a powerful CLI code generator for Go that helps you create Clean Architecture projects following best practices. It generates clean, well-structured layered code, allowing you to focus on business logic instead of repetitive configuration tasks.

Documentation

Clean Architecture Philosophy

Every feature generated by Goca strictly follows Clean Architecture principles:

  • 🟡 Domain Layer: Pure entities without external dependencies
  • 🔴 Use Case Layer: Application logic with DTOs and business validations
  • 🟢 Adapter Layer: HTTP, gRPC, CLI interfaces that adapt input/output
  • 🔵 Infrastructure Layer: Repositories that implement data persistence

✅ Best Practices Guaranteed

  • Dependencies oriented towards the system core
  • Clear interfaces and contracts between layers
  • Business logic encapsulated in internal layers
  • Clearly segregated responsibilities
  • Dependency injection for maximum testability

🚫 Bad Practices Prevention

  • Prevents mixing technical logic with business logic
  • Prevents direct dependencies from entities to infrastructure
  • Generates well-structured and cohesive packages

🧠 Implemented Principles and Anti-Patterns

✅ Applied Patterns

  • Repository Pattern: Data persistence abstraction
  • Dependency Injection: Inversion of control between layers
  • CQRS: Separation of commands and queries in use cases
  • Interface Segregation: Specific contracts per responsibility

🚫 Prevented Anti-Patterns

  • Fat Controller: Business logic in handlers
  • God Object: Entities with too many responsibilities
  • Anemic Domain Model: Entities without behavior
  • Direct Database Access: Direct dependencies to infrastructure

🔍 Clean Architecture Validation

Goca guarantees that every generated file complies with:

  • Dependency Rule: Internal code never depends on external code
  • Separation of Concerns: Each layer has a single reason to change
  • Inversion Principle: Details depend on abstractions
  • Clean Interfaces: Clear contracts between layers

🚀 Main Features

  • Layer-based Generation: Each command generates code specific to a Clean Architecture layer
  • Complete Feature: One command generates all necessary structure for a feature
  • Domain Entities: Generates pure entities with business validations
  • Use Cases: Creates application services with well-defined DTOs
  • Repositories: Generates interfaces and implementations following Repository Pattern
  • Multi-Protocol Handlers: Supports HTTP, gRPC, CLI maintaining layer separation
  • Dependency Injection: Structure prepared for DI from the start
  • Integration Testing: Auto-generate comprehensive integration tests with fixtures and helpers (v1.14.0+)

📦 Installation

Recommended: Binary from GitHub Releases

Download the latest stable version with proper version info from GitHub Releases:

Linux:

# Download latest release
wget https://github.com/sazardev/goca/releases/latest/download/goca-linux-amd64
chmod +x goca-linux-amd64
sudo mv goca-linux-amd64 /usr/local/bin/goca

# Verify installation
goca version

macOS:

# Intel Macs
wget https://github.com/sazardev/goca/releases/latest/download/goca-darwin-amd64
chmod +x goca-darwin-amd64
sudo mv goca-darwin-amd64 /usr/local/bin/goca

# Apple Silicon Macs  
wget https://github.com/sazardev/goca/releases/latest/download/goca-darwin-arm64
chmod +x goca-darwin-arm64
sudo mv goca-darwin-arm64 /usr/local/bin/goca

# Verify installation
goca version

Windows:

# Download goca-windows-amd64.exe from GitHub Releases
# Rename to goca.exe and add to PATH

# Verify installation
goca version

Alternative: Using Go Install

# Install from source (version info will show "dev")
go install github.com/sazardev/goca@latest

# Note: go install builds from source without version injection
# For proper version info, use binary releases above

For Development

# Clone and build with proper version injection
git clone https://github.com/sazardev/goca.git
cd goca
make build

# The binary will be created in current directory
# Move to PATH if needed:
sudo mv goca /usr/local/bin/goca

🛠️ Quick Start

Initialize Clean Architecture Project

# Create new project with Clean Architecture structure
goca init myproject --module github.com/sazardev/myproject

# Navigate to project
cd myproject

# Install dependencies
go mod tidy

Generate Complete Feature (NEW - Auto-Integrated)

# Generate complete feature with all layers + automatic integration
goca feature Employee --fields "name:string,email:string,role:string"

# Ready to go! The feature is completely functional
go run main.go

Integrate Existing Features (NEW)

# For projects with features not integrated
goca integrate --all

# Automatically detects all features and connects them

⚡ NEW in v1.11.0: Safety & Dependency Features

Goca now includes production-ready safety features to prevent common mistakes:

🛡️ Safety Features

  • 🔍 Dry-Run Mode (--dry-run): Preview all changes before creating files
  • ⚠️ File Conflict Detection: Automatically detects existing files to prevent accidental overwrites
  • 👤 Name Conflict Detection: Scans project for duplicate entity/feature names
  • 📦 Automatic Backup (--backup): Backup files before overwriting
  • 💪 Force Overwrite (--force): Override protection when needed
  • 📚 Version Compatibility: Verifies Go version compatibility (1.21+)

📦 Dependency Management

  • 🤖 Automatic go.mod Updates: Auto-updates dependencies when generating features
  • � Smart Suggestions: Recommends optional dependencies based on feature type
  • ✅ Version Verification: Validates dependency versions and integrity

Example Usage

# Preview changes before generating
goca feature User --fields "name:string,email:string" --dry-run

# Safe generation with conflict detection
goca feature User --fields "name:string,email:string"

# Update existing feature with backup
goca feature User --fields "name:string,email:string,role:string" --force --backup

📖 Complete Safety Features Documentation

�📋 Main Commands

Command Purpose Automatic Integration
goca init Initialize Clean Architecture project ✅ Complete structure + Git
goca feature Generate complete feature (all layers) ✅ Auto-DI + Routes + Safety
goca integrate NEW: Integrate existing features ✅ Repair/update integration
goca entity Generate domain entities only ❌ Manual
goca usecase Generate use cases only ❌ Manual
goca repository Generate repositories only ❌ Manual
goca handler Generate handlers only ❌ Manual
goca di Generate dependency injection container ❌ Manual

🔄 Recommended Workflow

  1. Generate Domain: goca entity Employee --fields "name:string,email:string"
  2. Generate Use Cases: goca usecase EmployeeService --entity Employee
  3. Generate Repository: goca repository Employee --database postgres
  4. Generate Handlers: goca handler Employee --type http
  5. Generate DI: goca di --features Employee

📚 Commands by Layer

🟡 Domain Layer

goca entity

Generates pure domain entities following DDD.

goca entity <name> [flags]

# Flags:
--fields string     Entity fields "name:type,email:string"
--validation       Add domain validations
--business-rules   Include business rule methods

Example:

goca entity Product --fields "name:string,price:float64,category:string" --validation --business-rules

Generated Code:

// domain/product.go
package domain

type Product struct {
    ID       int
    Name     string
    Price    float64
    Category string
}

func (p *Product) Validate() error {
    if p.Name == "" || p.Price <= 0 {
        return ErrInvalidProductData
    }
    return nil
}

func (p *Product) IsExpensive() bool {
    return p.Price > 1000.0
}

🔴 Use Case Layer

goca usecase

Generates application services with DTOs and business logic.

goca usecase <name> [flags]

# Flags:
--entity string    Associated entity
--operations string CRUD operations (create,read,update,delete,list)
--dto-validation   DTOs with specific validations

Example:

goca usecase ProductService --entity Product --operations "create,read,update,delete,list" --dto-validation

Generated Code:

// usecase/product_service.go
package usecase

import "myproject/domain"

type CreateProductInput struct {
    Name     string `validate:"required,min=3"`
    Price    float64 `validate:"required,gt=0"`
    Category string `validate:"required"`
}

type CreateProductOutput struct {
    Product domain.Product
    Message string
}

type ProductUseCase interface {
    CreateProduct(input CreateProductInput) (CreateProductOutput, error)
    GetProduct(id int) (domain.Product, error)
    UpdateProduct(id int, input UpdateProductInput) error
    DeleteProduct(id int) error
    ListProducts() ([]domain.Product, error)
}

🟢 Adapter Layer (Handlers)

goca handler

Generates delivery adapters for different protocols.

goca handler <entity> [flags]

# Flags:
--type string     Handler type (http, grpc, cli, worker, soap)
--middleware      Include middleware setup
--validation      Input validation in handler

HTTP Example:

goca handler Product --type http --middleware --validation

Generated Code:

// handler/http/product_handler.go
package http

import (
    "encoding/json"
    "net/http"
    "myproject/usecase"
)

type ProductHandler struct {
    usecase usecase.ProductUseCase
}

func NewProductHandler(uc usecase.ProductUseCase) *ProductHandler {
    return &ProductHandler{usecase: uc}
}

func (h *ProductHandler) CreateProduct(w http.ResponseWriter, r *http.Request) {
    var input usecase.CreateProductInput
    if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
        http.Error(w, "Invalid request body", http.StatusBadRequest)
        return
    }
    
    output, err := h.usecase.CreateProduct(input)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(output)
}

🔵 Infrastructure Layer

goca repository

Generates repositories with interfaces and implementations.

goca repository <entity> [flags]

# Flags:
--database string  Database type (postgres, mysql, mongodb)
--interface-only   Generate interfaces only
--implementation   Generate implementation only

Example:

goca repository Product --database postgres

Generated Code:

// repository/interfaces/product_repository.go
package interfaces

import "myproject/domain"

type ProductRepository interface {
    Save(product *domain.Product) error
    FindByID(id int) (*domain.Product, error)
    FindAll() ([]domain.Product, error)
    Update(product *domain.Product) error
    Delete(id int) error
}

// repository/postgres/product_repository.go
package postgres

import (
    "database/sql"
    "myproject/domain"
    "myproject/repository/interfaces"
)

type postgresProductRepository struct {
    db *sql.DB
}

func NewPostgresProductRepository(db *sql.DB) interfaces.ProductRepository {
    return &postgresProductRepository{db: db}
}

func (r *postgresProductRepository) Save(product *domain.Product) error {
    query := `INSERT INTO products (name, price, category) VALUES ($1, $2, $3) RETURNING id`
    err := r.db.QueryRow(query, product.Name, product.Price, product.Category).Scan(&product.ID)
    return err
}

Auxiliary Commands

goca messages

Generates message and constant files.

goca messages <entity> [flags]

# Flags:
--errors       Generate error messages
--responses    Generate response messages
--constants    Generate feature constants

📁 Complete Structure per Feature (Example: Employee)

employee/
├── domain/
│   ├── employee.go          # Pure entity
│   ├── errors.go           # Domain errors
│   └── validations.go      # Business validations
├── usecase/
│   ├── dto.go              # Input/output DTOs
│   ├── employee_usecase.go # Use case interface
│   ├── employee_service.go # Use case implementation
│   └── interfaces.go       # Contracts to other layers
├── repository/
│   ├── interfaces.go       # Persistence contracts
│   ├── postgres_employee_repo.go  # PostgreSQL implementation
│   └── memory_employee_repo.go    # In-memory implementation
├── handler/
│   ├── http/
│   │   ├── dto.go          # HTTP-specific DTOs
│   │   └── handler.go      # HTTP controller
│   ├── grpc/
│   │   ├── employee.proto  # gRPC definition
│   │   └── server.go       # gRPC server
│   ├── cli/
│   │   └── commands.go     # CLI commands
│   ├── worker/
│   │   └── worker.go       # Workers/Jobs
│   └── soap/
│       └── soap_client.go  # SOAP client
├── messages/
│   ├── errors.go           # Error messages
│   └── responses.go        # Response messages
├── constants/
│   └── constants.go        # Feature constants
└── main.go                 # Entry point

📋 Best vs Bad Practices by Layer

🟡 Domain - What to DO and NOT do

✅ Best Practices:

// ✅ Pure entity with business validations
type Employee struct {
    ID    int
    Name  string
    Email string
    Role  string
}

func (e *Employee) Validate() error {
    if e.Name == "" || e.Email == "" {
        return ErrInvalidEmployeeData
    }
    return nil
}

func (e *Employee) IsManager() bool {
    return e.Role == "manager"
}

❌ Bad Practices:

// ❌ NEVER: Infrastructure dependencies in domain
type Employee struct {
    ID int
    DB *sql.DB // ❌ External dependency
}

// ❌ NEVER: Technical logic in domain
func (e *Employee) SaveToDatabase() error // ❌ Wrong responsibility

// ❌ NEVER: Import packages from external layers
import "myproject/handler/http" // ❌ Dependency violation

🔴 Use Cases - What to DO and NOT do

✅ Best Practices:

// ✅ Well-defined DTOs
type CreateEmployeeInput struct {
    Name  string `validate:"required"`
    Email string `validate:"required,email"`
}

// ✅ Interfaces to other layers
type EmployeeRepository interface {
    Save(*domain.Employee) error
}

// ✅ Pure application logic
func (s *EmployeeService) CreateEmployee(input CreateEmployeeInput) error {
    emp := domain.Employee{Name: input.Name, Email: input.Email}
    if err := emp.Validate(); err != nil {
        return err
    }
    return s.repo.Save(&emp)
}

❌ Bad Practices:

// ❌ NEVER: Direct infrastructure dependencies
func (s *EmployeeService) CreateEmployee(db *sql.DB) error // ❌ Coupling

// ❌ NEVER: Presentation logic
func (s *EmployeeService) CreateEmployeeJSON() string // ❌ Wrong responsibility

// ❌ NEVER: Implementation details
func (s *EmployeeService) CreateEmployeeWithPostgres() error // ❌ Technical specificity

🟢 Adapters - What to DO and NOT do

✅ Best Practices:

// ✅ Data transformation only
func (h *EmployeeHandler) CreateEmployee(w http.ResponseWriter, r *http.Request) {
    var httpInput HTTPCreateEmployeeInput
    json.NewDecoder(r.Body).Decode(&httpInput)
    
    usecaseInput := usecase.CreateEmployeeInput{
        Name:  httpInput.Name,
        Email: httpInput.Email,
    }
    
    err := h.usecase.CreateEmployee(usecaseInput)
    // Handle HTTP response
}

❌ Bad Practices:

// ❌ NEVER: Business logic in handlers
func (h *EmployeeHandler) CreateEmployee(w http.ResponseWriter, r *http.Request) {
    // ❌ Business validations here
    if employee.Salary < 0 {
        return errors.New("invalid salary")
    }
}

// ❌ NEVER: Direct repository access
func (h *EmployeeHandler) CreateEmployee(repo EmployeeRepository) // ❌ Skip use cases

🔵 Infrastructure - What to DO and NOT do

✅ Best Practices:

// ✅ Specific persistence implementation
func (r *PostgresEmployeeRepo) Save(emp *domain.Employee) error {
    query := "INSERT INTO employees (name, email) VALUES ($1, $2)"
    _, err := r.db.Exec(query, emp.Name, emp.Email)
    return err
}

// ✅ Implement domain interfaces
func NewPostgresEmployeeRepo(db *sql.DB) domain.EmployeeRepository {
    return &PostgresEmployeeRepo{db: db}
}

❌ Bad Practices:

// ❌ NEVER: Expose specific DB types
func (r *PostgresEmployeeRepo) GetDB() *sql.DB // ❌ Technical detail exposed

// ❌ NEVER: Business logic in repositories
func (r *PostgresEmployeeRepo) ValidateAndSave(emp *domain.Employee) error {
    if emp.Salary < 0 { // ❌ Business validation here
        return errors.New("invalid salary")
    }
}

🔧 Advanced Commands

Generate Complete Feature

# Generates all layers for a feature
goca feature <name> --fields "field:type,..." --database postgres --handlers "http,grpc,cli"

Generate Interfaces Only

# Useful for TDD - generate contracts first
goca interfaces Product --usecase --repository

Generate Dependency Injection

# Generates DI container for automatic wiring
goca di --features "Product,User,Order"

🎯 Advantages of Each Layer

🟡 Domain

  • Pure entities without external dependencies
  • Business rules centralized and testable
  • Domain-specific validations

🔴 Use Cases

  • Specific DTOs for each operation
  • Well-defined application logic
  • Clear interfaces to other layers

🟢 Adapters

  • Complete separation between input protocols
  • Protocol-specific input validations
  • Transformation from external to internal DTOs

🔵 Infrastructure

  • Interchangeable implementations of persistence
  • Isolation of technical details
  • Centralized configuration of external resources

🔄 Dependency Flow

Handler → UseCase → Repository → Database
   ↓         ↓         ↓
 DTO ←→ Business ←→ Domain Entity

Golden Rule: Dependencies always point inward, towards the domain.

📚 Complete Documentation

Configuration System

Integration & Status

Advanced Topics

🤝 Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/clean-arch-enhancement)
  3. Commit your changes (git commit -m 'Add enhanced clean architecture layer')
  4. Push to the branch (git push origin feature/clean-arch-enhancement)
  5. Open a Pull Request

📄 License

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

🆘 Support


Built with ❤️ for the Go community

About

Goca is a powerful CLI code generator for Go that helps you create Clean Architecture projects following best practices.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published

Contributors 3

  •  
  •  
  •