docs: Add comprehensive system architecture diagrams

Created detailed ASCII diagrams documenting the entire system architecture:

1. System Architecture (_go-learning/diagrams/01-system-architecture.md)
   - Overall system architecture with client/server/storage layers
   - Layered architecture (Presentation → Application → Business → Data)
   - Component interaction and HTTP request flow
   - Data flow from app start through per-request lifecycle
   - Package dependencies and file organization
This commit is contained in:
juanatsap
2025-11-20 20:17:29 +00:00
parent 9015cef098
commit faf3a2ca45
11 changed files with 4160 additions and 0 deletions
+219
View File
@@ -0,0 +1,219 @@
# 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
1. **[Middleware Pattern](./01-middleware-pattern.md)** - HTTP middleware chain for cross-cutting concerns
2. **[Handler Pattern](./02-handler-pattern.md)** - Organized HTTP handler structure
3. **[Context Pattern](./03-context-pattern.md)** - Request-scoped values using context
4. **[Error Wrapping](./04-error-wrapping.md)** - Structured error handling with wrapping
5. **[Dependency Injection](./05-dependency-injection.md)** - Constructor-based dependency injection
6. **[Template Pattern](./06-template-pattern.md)** - Cached template management
7. **[Singleton Pattern](./07-singleton-pattern.md)** - Single instance managers (template, config)
8. **[Factory Pattern](./08-factory-pattern.md)** - 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
```go
// BAD: Mutable global variable
var globalConfig Config
// GOOD: Pass as dependency
func NewHandler(config *Config) *Handler
```
### ❌ Panic for Flow Control
```go
// 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
```go
// 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
```go
// 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
```go
// 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:
1. **Start with**: Handler Pattern, Error Wrapping
2. **Then learn**: Middleware Pattern, Context Pattern
3. **Advanced**: Dependency Injection, Template Pattern
4. **Master**: Singleton Pattern, Factory Pattern
## Resources
- [Effective Go](https://golang.org/doc/effective_go) - Official Go style guide
- [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments) - Common mistakes
- [Practical Go](https://dave.cheney.net/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