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
Go Patterns Used in This Project
This directory contains documentation on the Go design patterns and idioms used throughout the CV website project.
Pattern Catalog
- Middleware Pattern - HTTP middleware chain for cross-cutting concerns
- Handler Pattern - Organized HTTP handler structure
- Context Pattern - Request-scoped values using context
- Error Wrapping - Structured error handling with wrapping
- Dependency Injection - Constructor-based dependency injection
- Template Pattern - Cached template management
- Singleton Pattern - Single instance managers (template, config)
- Factory Pattern - Error and response constructors
Pattern Categories
Structural Patterns
- Middleware Pattern - Composable request processing
- Singleton Pattern - Single instance coordination
- Dependency Injection - Decoupled component initialization
Behavioral Patterns
- Handler Pattern - Request routing and handling
- Context Pattern - Request-scoped data propagation
- Template Pattern - Flexible rendering engine
Error Handling Patterns
- Error Wrapping - Context-rich error chains
- Typed Errors - Domain-specific error types
- Factory Pattern - Consistent error creation
Pattern Usage Map
┌────────────────────────────────────────────────────────────┐
│ Pattern Usage Map │
└────────────────────────────────────────────────────────────┘
main.go
├─→ Singleton Pattern (config, template manager)
├─→ Dependency Injection (handler construction)
└─→ Middleware Pattern (chain setup)
internal/handlers/
├─→ Handler Pattern (method organization)
├─→ Error Wrapping (error handling)
├─→ Factory Pattern (error/response creation)
└─→ Context Pattern (preference access)
internal/middleware/
├─→ Middleware Pattern (http.Handler wrapping)
├─→ Context Pattern (value storage)
└─→ Error Wrapping (panic recovery)
internal/templates/
├─→ Singleton Pattern (manager instance)
├─→ Template Pattern (rendering strategy)
└─→ Dependency Injection (config injection)
internal/models/
├─→ Factory Pattern (model loading)
└─→ Error Wrapping (validation errors)
When to Use Each Pattern
Middleware Pattern
✓ Cross-cutting concerns (logging, auth, CORS) ✓ Request/response modification ✓ Chain-of-responsibility needs ✗ Business logic (use handlers instead)
Handler Pattern
✓ HTTP request handling ✓ Route-specific logic ✓ Organizing endpoints by resource ✗ Generic utilities (use packages instead)
Context Pattern
✓ Request-scoped values (user, preferences) ✓ Cancellation signals ✓ Deadlines and timeouts ✗ Function parameters (use explicit params)
Error Wrapping
✓ Adding context to errors ✓ Preserving error chains ✓ Debug information ✗ Simple errors (use errors.New)
Dependency Injection
✓ Decoupling components ✓ Testing with mocks ✓ Configuration flexibility ✗ Simple functions (use direct calls)
Template Pattern
✓ Flexible rendering ✓ HTML generation ✓ Hot reload in development ✗ JSON APIs (use direct encoding)
Singleton Pattern
✓ Shared resources (DB, cache) ✓ Configuration managers ✓ Template engines ✗ Stateless utilities (use packages)
Factory Pattern
✓ Complex object creation ✓ Consistent initialization ✓ Error construction ✗ Simple structs (use literals)
Anti-Patterns to Avoid
❌ Global State
// BAD: Mutable global variable
var globalConfig Config
// GOOD: Pass as dependency
func NewHandler(config *Config) *Handler
❌ Panic for Flow Control
// BAD: Using panic for expected errors
if err != nil {
panic(err)
}
// GOOD: Return errors
if err != nil {
return fmt.Errorf("operation failed: %w", err)
}
❌ Ignoring Errors
// BAD: Ignoring error
_ = json.Unmarshal(data, &result)
// GOOD: Handle error
if err := json.Unmarshal(data, &result); err != nil {
return fmt.Errorf("unmarshal: %w", err)
}
❌ Context in Structs
// BAD: Storing context in struct
type Handler struct {
ctx context.Context
}
// GOOD: Pass context as first parameter
func (h *Handler) Handle(ctx context.Context, w, r)
❌ Naked Returns
// BAD: Naked return with named results
func process() (result string, err error) {
result = "foo"
return // Confusing!
}
// GOOD: Explicit return
func process() (string, error) {
result := "foo"
return result, nil
}
Learning Path
For developers new to these patterns:
- Start with: Handler Pattern, Error Wrapping
- Then learn: Middleware Pattern, Context Pattern
- Advanced: Dependency Injection, Template Pattern
- Master: Singleton Pattern, Factory Pattern
Resources
- Effective Go - Official Go style guide
- Go Code Review Comments - Common mistakes
- Practical Go - Best practices
Pattern Evolution
This project evolved through these pattern adoptions:
Phase 1: Basic Structure
- Simple handlers
- No middleware
- Manual cookie reading
Phase 2: Middleware Introduction
- PreferencesMiddleware added
- Cookie handling centralized
- Context pattern adopted
Phase 3: Type Safety
- Request/response types
- Validation tags
- Typed errors
Phase 4: Error Handling
- Error wrapping throughout
- Domain error types
- Centralized error handler
Phase 5: Testing
- Dependency injection for testability
- Mock-friendly interfaces
- Benchmark tests