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

Repository files navigation

Goca - Go Clean Architecture Code Generator

Go Version License Build Status 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.

📚 Complete Documentation | 🚀 Quick Start Guide | 📖 Complete Tutorial

🏗️ 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

📦 Installation

Using Go Install (Recommended)

go install github.com/sazardev/goca@latest

Binary Downloads

Download binaries directly from GitHub Releases:

Windows:

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

Linux:

# Download and make executable
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

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

From Source

git clone https://github.com/sazardev/goca.git
cd goca
go build -o 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

📋 Main Commands

Command Purpose Automatic Integration
goca init Initialize Clean Architecture project ✅ Complete structure
goca feature Generate complete feature (all layers) NEW: Auto-DI + Routes
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.

🤝 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

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •