Files
cv-site/_go-learning/best-practices
juanatsap 219b83bfc0 docs: Complete _go-learning documentation with diagrams, patterns, and best practices
Added comprehensive educational documentation to fill empty folders:

## Architecture Diagrams (8 files)
- System architecture with layered design
- Complete request/response flow diagrams
- Middleware chain execution details
- Handler organization structure
- Data model relationships
- Error handling flows
- Template rendering pipeline
- PDF generation process with Chromedp

## Go Patterns (9 files)
- Pattern catalog and usage guide
- Middleware pattern (HTTP chain composition)
- Handler pattern (method-based organization)
- Context pattern (request-scoped values)
- Error wrapping (typed errors, chains)
- Dependency injection (constructor-based)
- Template pattern (rendering pipeline)
- Singleton pattern (thread-safe instances)
- Factory pattern (error/response constructors)

## Best Practices (2 files)
- Best practices catalog and quick reference
- Code organization (project structure, naming)

All documentation includes:
- Real examples from this project
- ASCII diagrams for visualization
- Best practices and anti-patterns
- Testing examples
- Performance considerations

Documentation structure:
- 20 markdown files
- ~6,000+ lines of educational content
- Cross-referenced between topics
- Practical, project-based examples
2025-11-20 20:27:38 +00:00
..

Go Best Practices for This Project

This directory contains best practices and guidelines used in the CV website project, demonstrating real-world Go development standards.

Best Practices Catalog

  1. Code Organization - Package structure, file naming, project layout
  2. Error Handling - Error wrapping, custom errors, error patterns
  3. Testing - Unit tests, integration tests, benchmarks, test organization
  4. Performance - Optimization strategies, profiling, benchmarking
  5. Security - Input validation, XSS prevention, CSRF protection
  6. HTTP & Handlers - Handler patterns, middleware, request/response
  7. HTMX Integration - Server-side rendering, partial updates, Go + HTMX patterns

Quick Reference

Code Organization

project/
├── cmd/              Main applications
├── internal/         Private application code
│   ├── handlers/     HTTP handlers
│   ├── middleware/   HTTP middleware
│   ├── models/       Data models
│   ├── templates/    Template management
│   └── routes/       Route definitions
├── data/             Static data files
├── templates/        HTML templates
├── static/           Static assets
└── tests/            Test files

Error Handling

// Wrap errors with context
if err != nil {
    return fmt.Errorf("operation failed: %w", err)
}

// Use typed errors
func InvalidLanguageError(lang string) *DomainError {
    return NewDomainError(
        ErrCodeInvalidLanguage,
        fmt.Sprintf("Unsupported language: %s", lang),
        http.StatusBadRequest,
    )
}

Testing

// Table-driven tests
func TestFunction(t *testing.T) {
    tests := []struct {
        name string
        input string
        want string
    }{
        {"case1", "input1", "expected1"},
        {"case2", "input2", "expected2"},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got := Function(tt.input)
            if got != tt.want {
                t.Errorf("got %v, want %v", got, tt.want)
            }
        })
    }
}

HTTP Handlers

// Use method receivers for related handlers
type CVHandler struct {
    tmpl *templates.Manager
    host string
}

func (h *CVHandler) Home(w http.ResponseWriter, r *http.Request) {
    // Handler logic
}

Middleware

// Standard middleware pattern
func MyMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Pre-processing
        next.ServeHTTP(w, r)
        // Post-processing
    })
}

Core Principles

1. Simplicity

  • Clear is better than clever
  • Explicit is better than implicit
  • Simple solutions over complex ones

2. Readability

  • Code is read more often than written
  • Use descriptive names
  • Comment why, not what

3. Consistency

  • Follow established patterns
  • Consistent formatting (gofmt)
  • Consistent error handling

4. Performance

  • Measure before optimizing
  • Use profiling tools
  • Optimize hot paths only

5. Security

  • Validate all input
  • Use context for timeouts
  • Sanitize output

Common Pitfalls to Avoid

DON'T

// DON'T ignore errors
data, _ := readFile(path)

// DON'T use panic for flow control
if invalid {
    panic("invalid input")
}

// DON'T store context in structs
type Handler struct {
    ctx context.Context  // Wrong!
}

// DON'T use global mutable state
var globalConfig Config
globalConfig.Timeout = 30

// DON'T return naked values with named returns
func foo() (result string, err error) {
    result = "value"
    return  // Confusing!
}

DO

// DO handle errors explicitly
data, err := readFile(path)
if err != nil {
    return fmt.Errorf("read file: %w", err)
}

// DO return errors for exceptional cases
if invalid {
    return errors.New("invalid input")
}

// DO pass context as first parameter
func (h *Handler) Process(ctx context.Context, data Data) error {
    // Use ctx
}

// DO use dependency injection
func NewHandler(config *Config) *Handler {
    return &Handler{config: config}
}

// DO use explicit returns
func foo() (string, error) {
    result := "value"
    return result, nil
}

Tools & Commands

Formatting & Linting

# Format code
go fmt ./...
gofmt -s -w .

# Lint code
golangci-lint run
staticcheck ./...

# Vet code
go vet ./...

Testing

# Run tests
go test ./...

# Run with coverage
go test -cover ./...
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out

# Run benchmarks
go test -bench=. ./...
go test -bench=. -benchmem ./...

# Run specific test
go test -run TestFunctionName

Profiling

# CPU profiling
go test -cpuprofile=cpu.prof -bench=.
go tool pprof cpu.prof

# Memory profiling
go test -memprofile=mem.prof -bench=.
go tool pprof mem.prof

# Live profiling
go tool pprof http://localhost:8080/debug/pprof/profile

Build & Run

# Build
go build -o app ./cmd/server

# Run
go run ./cmd/server

# Build with optimizations
go build -ldflags="-s -w" -o app ./cmd/server

# Cross-compile
GOOS=linux GOARCH=amd64 go build -o app-linux ./cmd/server

Project-Specific Guidelines

File Naming

  • handler.gocv.go, health.go
  • handler_pages.gocv_pages.go
  • handler_htmx.gocv_htmx.go
  • handler_test.gocv_pages_test.go

Handler Organization

internal/handlers/
├── cv.go              # Constructor
├── cv_pages.go        # Page handlers
├── cv_htmx.go         # HTMX handlers
├── cv_pdf.go          # PDF handler
├── cv_helpers.go      # Helper functions
├── types.go           # Request/response types
├── errors.go          # Error handling
└── *_test.go          # Tests mirror source files

Middleware Chain Order

Recovery → Logger → SecurityHeaders → Preferences → Router
(outer)                                              (inner)

Context Keys

// Use custom type for context keys
type contextKey string
const PreferencesKey contextKey = "preferences"

References

Official Resources

Community Resources

Tools

Learning Path

  1. Start with: Code Organization, HTTP Handlers
  2. Then learn: Error Handling, Testing
  3. Advanced: Performance, Security
  4. Mastery: HTMX Integration, Full Stack Patterns

Evolution of This Project

Phase 1: Basic Structure

  • Simple handlers
  • No middleware
  • Manual cookie handling

Phase 2: Refactoring

  • Handler split by responsibility
  • Middleware introduction
  • Context pattern adoption

Phase 3: Type Safety

  • Request/response types
  • Validation tags
  • Typed errors

Phase 4: Testing & Performance

  • Comprehensive test coverage
  • Benchmark tests
  • Performance profiling

Phase 5: Documentation

  • Architecture diagrams
  • Pattern documentation
  • Best practices guide (this!)