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
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
- 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
- Prevents mixing technical logic with business logic
- Prevents direct dependencies from entities to infrastructure
- Generates well-structured and cohesive packages
- 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
- 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
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
- 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
go install github.com/sazardev/goca@latest
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
git clone https://github.com/sazardev/goca.git
cd goca
go build -o goca
# 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 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
# For projects with features not integrated
goca integrate --all
# Automatically detects all features and connects them
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 |
- Generate Domain:
goca entity Employee --fields "name:string,email:string"
- Generate Use Cases:
goca usecase EmployeeService --entity Employee
- Generate Repository:
goca repository Employee --database postgres
- Generate Handlers:
goca handler Employee --type http
- Generate DI:
goca di --features Employee
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
}
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)
}
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)
}
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
}
Generates message and constant files.
goca messages <entity> [flags]
# Flags:
--errors Generate error messages
--responses Generate response messages
--constants Generate feature constants
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
// ✅ 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"
}
// ❌ 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
// ✅ 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)
}
// ❌ 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
// ✅ 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
}
// ❌ 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
// ✅ 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}
}
// ❌ 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")
}
}
# Generates all layers for a feature
goca feature <name> --fields "field:type,..." --database postgres --handlers "http,grpc,cli"
# Useful for TDD - generate contracts first
goca interfaces Product --usecase --repository
# Generates DI container for automatic wiring
goca di --features "Product,User,Order"
- Pure entities without external dependencies
- Business rules centralized and testable
- Domain-specific validations
- Specific DTOs for each operation
- Well-defined application logic
- Clear interfaces to other layers
- Complete separation between input protocols
- Protocol-specific input validations
- Transformation from external to internal DTOs
- Interchangeable implementations of persistence
- Isolation of technical details
- Centralized configuration of external resources
Handler → UseCase → Repository → Database
↓ ↓ ↓
DTO ←→ Business ←→ Domain Entity
Golden Rule: Dependencies always point inward, towards the domain.
- Fork the repository
- Create your feature branch (
git checkout -b feature/clean-arch-enhancement
) - Commit your changes (
git commit -m 'Add enhanced clean architecture layer'
) - Push to the branch (
git push origin feature/clean-arch-enhancement
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- 📧 Email: support@goca.dev
- 🐛 Issues: GitHub Issues
- 📖 Documentation: Complete Documentation
Built with ❤️ for the Go community