forge Framework - Design Documentation
Overview
forge is a Django-inspired Go web framework that combines the developer experience of Django with Go's type safety and performance. The framework is designed to be type-safe first, with dynamic capabilities when needed.
Core Design Principles
1. Type-Safe First
- Primary API uses Go generics for compile-time type checking
- All queries, models, and operations are type-safe
- IDE autocomplete and refactoring support
- Compile-time error detection
2. Dynamic When Needed
- Secondary API for runtime flexibility
- Dynamic query building for complex scenarios
- Runtime schema introspection
- Plugin system for extensibility
3. Convention over Configuration
- Sensible defaults everywhere
- Django-like patterns and naming
- Minimal boilerplate
- Auto-generated code where possible
4. Fully Extensible
- Everything can be extended or overridden
- Plugin architecture
- Hook system for lifecycle events
- Custom validators, filters, widgets
5. Security by Default
- Built-in CSRF protection
- XSS prevention
- SQL injection prevention via parameter binding
- Input validation and sanitization
6. Code Generation
- AST-based code generation
- Type-safe model code generation
- Manager and QuerySet generation
- Reduces boilerplate while maintaining type safety
Design Patterns
Builder Pattern
Used extensively for:
- Field definitions (
fields.String("name").Required().MaxLength(100)) - Query building (method chaining)
- Configuration setup
Registry Pattern
- Model registry for admin system
- Plugin registry for extensions
- Authentication backend registry
Factory Pattern
- Server creation
- Router setup
- Logger creation
- Identity system setup
Repository Pattern
- Data access layer abstraction
- Used in identity system
- Clean separation of concerns
Strategy Pattern
- Authentication backends
- Cache backends
- Renderers and parsers
- Filter widgets
Type System Design
Generics Usage
QuerySet[T]- Type-safe query setsManager[T]- Type-safe model managersAdmin[T]- Type-safe admin interfaceFieldExpr[T]- Type-safe field expressionsFilter[T]- Type-safe filters
Interface Design
- Small, focused interfaces
- Composition over inheritance
- Dependency injection friendly
Architecture Layers
┌─────────────────────────────────────────┐
│ User Application Layer │
│ (Models, Views, Controllers, Routes) │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Code Generation Layer │
│ (AST Parser → Code Generator) │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Framework API Layer │
│ (QuerySet, Manager, Admin, API) │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Database Layer │
│ (SQL Builder, Transactions, Migrations) │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Infrastructure Layer │
│ (HTTP, Security, Logging, Config) │
└─────────────────────────────────────────┘
API Design Philosophy
Fluent Interface
Method chaining for readable code:
users, err := User.Objects.
Filter(User.Fields.IsActive.Equals(true)).
OrderBy("-created_at").
Limit(10).
All(ctx)
Django-Inspired
Familiar patterns for Django developers:
- Model definitions
- Admin interface
- QuerySet API
- Manager patterns
Composable
APIs can be combined and extended:
- Custom QuerySet methods
- Custom admin actions
- Custom filters
- Custom validators
Error Handling Design
Structured Errors
- Error types with context
- Error wrapping for traceability
- Validation errors with field information
Error Recovery
- Graceful degradation
- Fallback mechanisms
- Clear error messages
Performance Design
Zero-Copy Where Possible
- Efficient data structures
- Minimal allocations
- Connection pooling
Lazy Loading
- Relations loaded on demand
- Query execution deferred
- Resource initialization on first use
Caching Strategy
- Query result caching
- Model instance caching
- Cache invalidation hooks
Security Design
Defense in Depth
- Multiple layers of security
- Input validation at all levels
- Output sanitization
- Secure defaults
Principle of Least Privilege
- Permission system
- Role-based access control
- Resource-level permissions
Testing Design
Testability
- Dependency injection
- Interface-based design
- Mockable components
- Test utilities
Test Coverage
- Unit tests for core functionality
- Integration tests for workflows
- E2E tests for critical paths
Extensibility Design
Plugin System
- Register plugins at startup
- Plugin lifecycle hooks
- Plugin dependencies
- Plugin configuration
Hook System
- Model lifecycle hooks
- Request/response hooks
- Admin hooks
- Validation hooks
Migration Design
Version Control
- Migration files tracked in version control
- Migration state in database
- Rollback support
Safety
- Transaction-wrapped migrations
- Schema validation
- Data migration support
Logging Design
Structured Logging
- JSON output format
- Contextual information
- Log levels
- Multiple outputs (console, file, remote)
Performance
- Async logging where possible
- Sampling in production
- Configurable log levels
Configuration Design
Multiple Sources
- YAML files
- JSON files
- Environment variables
- Command-line flags
Hierarchical
- Default values
- Environment-specific overrides
- Application-specific config
Future Design Considerations
Scalability
- Horizontal scaling support
- Stateless design
- Database sharding support
Observability
- Metrics collection
- Distributed tracing
- Health checks
Developer Experience
- Better error messages
- Development tools
- Hot reload
- Debug toolbar