BREAKING CHANGES:
- Renamed HandleGET -> MemberGET for member-level routes
- Renamed HandlePOST -> MemberPOST for member-level routes
- Renamed HandlePUT -> MemberPUT for member-level routes
- Renamed HandlePATCH -> MemberPATCH for member-level routes
- Renamed HandleDELETE -> MemberDELETE for member-level routes
New Features:
- Added collection-level route methods: GET, POST, PUT, PATCH, DELETE
- Clear distinction between collection (/pattern/action) and member (/pattern/{id}/action) routes
- Comprehensive documentation (README, CONTRIBUTING, QUICKSTART, DOCS)
- Development tooling (Makefile, check.sh script)
- AI coding assistant guidelines (.cursorrules)
- GitHub Actions CI/CD pipeline
- golangci-lint configuration
Code Quality:
- Optimized struct field alignment for better memory usage
- All code passes go vet, staticcheck, and fieldalignment
- All tests pass with race detector
- Go 1.25+ requirement enforced
Documentation:
- Complete README rewrite with examples
- CONTRIBUTING.md with development guidelines
- QUICKSTART.md for new users
- CHANGELOG.md with version history
- SUMMARY.md documenting all changes
- DOCS.md as documentation index
295 lines
8.4 KiB
Plaintext
295 lines
8.4 KiB
Plaintext
# Mux Project - AI Coding Assistant Rules
|
|
|
|
## Project Overview
|
|
This is a lightweight HTTP router for Go that wraps the standard library's http.ServeMux.
|
|
The project emphasizes simplicity, performance, and zero external dependencies.
|
|
|
|
## Language and Version Requirements
|
|
- **Language**: Go
|
|
- **Minimum Version**: Go 1.25+
|
|
- **Standard Library Only**: No external dependencies except for optional middleware examples
|
|
|
|
## Code Quality Standards
|
|
|
|
### Mandatory Checks
|
|
All code MUST pass these checks before committing:
|
|
|
|
1. **go vet**: `go vet ./...`
|
|
- Catches common mistakes and suspicious constructs
|
|
- Must pass with zero warnings
|
|
|
|
2. **staticcheck**: `staticcheck ./...`
|
|
- Advanced static analysis
|
|
- Catches bugs, inefficiencies, and style issues
|
|
- Must pass with zero warnings
|
|
|
|
3. **fieldalignment**: `go vet -vettool=$(which fieldalignment) ./...`
|
|
- Ensures optimal struct field ordering
|
|
- Minimizes memory usage through proper alignment
|
|
- Apply fixes when suggested
|
|
|
|
4. **Tests with Race Detection**: `go test -race ./...`
|
|
- All tests must pass
|
|
- No race conditions allowed
|
|
|
|
### Running All Checks
|
|
```bash
|
|
go vet ./...
|
|
staticcheck ./...
|
|
go test -race ./...
|
|
go vet -vettool=$(which fieldalignment) ./...
|
|
```
|
|
|
|
## Code Style and Conventions
|
|
|
|
### General Principles
|
|
- **Simplicity First**: Prefer clear, straightforward code over clever solutions
|
|
- **Zero Allocations**: Optimize hot paths to minimize heap allocations
|
|
- **Standard Library**: Use only Go standard library unless absolutely necessary
|
|
- **Fail Fast**: Use panics for programmer errors, return errors for runtime issues
|
|
- **No Reflection**: Avoid runtime reflection for performance reasons
|
|
|
|
### Naming Conventions
|
|
- Use `MixedCaps` or `mixedCaps` (not snake_case)
|
|
- Short names for local variables (i, err, w, r, etc.)
|
|
- Descriptive names for exported identifiers
|
|
- Avoid package name stuttering (mux.Mux, not mux.MuxRouter)
|
|
- Use conventional names: `m` for Mux, `res` for Resource, `w` for ResponseWriter, `r` for Request
|
|
|
|
### Function and Method Design
|
|
- Keep functions small and focused (prefer < 50 lines)
|
|
- One level of abstraction per function
|
|
- Early returns to reduce nesting
|
|
- Validate inputs early (fail fast)
|
|
|
|
### Error Handling
|
|
- Never ignore errors (no `_` for error returns unless documented why)
|
|
- Use `panic()` for programmer errors (nil checks, invalid configs)
|
|
- Return errors for runtime failures
|
|
- Provide context in error messages
|
|
- Use standard error wrapping: `fmt.Errorf("context: %w", err)`
|
|
|
|
### Comments and Documentation
|
|
- All exported functions, types, and methods MUST have comments
|
|
- Comments start with the name being described
|
|
- Use complete sentences with proper punctuation
|
|
- Explain "why" not "what" for complex logic
|
|
- Update comments when changing code
|
|
|
|
Example:
|
|
```go
|
|
// New creates and returns a new Mux router instance with an empty route table
|
|
// and no middleware configured.
|
|
func New() *Mux {
|
|
return &Mux{
|
|
mux: http.NewServeMux(),
|
|
routes: new(RouteList),
|
|
}
|
|
}
|
|
```
|
|
|
|
### Struct Field Ordering
|
|
Always order struct fields by size (largest to smallest) for optimal memory alignment:
|
|
|
|
```go
|
|
// Good - optimally aligned
|
|
type Resource struct {
|
|
mux *http.ServeMux // 8 bytes (pointer)
|
|
pattern string // 16 bytes (string header)
|
|
middlewares []func(http.Handler) http.Handler // 24 bytes (slice header)
|
|
routes *RouteList // 8 bytes (pointer)
|
|
}
|
|
|
|
// Bad - poor alignment
|
|
type Resource struct {
|
|
pattern string
|
|
mux *http.ServeMux
|
|
routes *RouteList
|
|
middlewares []func(http.Handler) http.Handler
|
|
}
|
|
```
|
|
|
|
## Project-Specific Patterns
|
|
|
|
### Middleware Signature
|
|
All middleware must follow the standard signature:
|
|
```go
|
|
func middleware(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
// pre-processing
|
|
next.ServeHTTP(w, r)
|
|
// post-processing
|
|
})
|
|
}
|
|
```
|
|
|
|
### Nil Checks
|
|
All public methods must check for nil receivers and panic with clear messages:
|
|
```go
|
|
func (m *Mux) Use(h ...func(http.Handler) http.Handler) {
|
|
if m == nil {
|
|
panic("mux: Use() called on nil")
|
|
}
|
|
m.middlewares = append(m.middlewares, h...)
|
|
}
|
|
```
|
|
|
|
### Route Pattern Validation
|
|
- Always validate pattern strings are non-empty
|
|
- Ensure patterns start with "/"
|
|
- Add prefix "/" if missing (normalize patterns)
|
|
|
|
### Resource Routing Conventions
|
|
- **Collection routes**: Operate on `/pattern/action` (use `POST`, `GET`, etc.)
|
|
- **Member routes**: Operate on `/pattern/{id}/action` (use `MemberPOST`, `MemberGET`, etc.)
|
|
- Always use `{id}` as the parameter name for resource identifiers
|
|
|
|
## Testing Requirements
|
|
|
|
### Test Structure
|
|
Use Arrange-Act-Assert pattern:
|
|
```go
|
|
func TestFeature(t *testing.T) {
|
|
// Arrange
|
|
m := mux.New()
|
|
|
|
// Act
|
|
m.GET("/test", handler)
|
|
|
|
// Assert
|
|
if got != want {
|
|
t.Errorf("got %v, want %v", got, want)
|
|
}
|
|
}
|
|
```
|
|
|
|
### Test Coverage
|
|
- All exported functions must have tests
|
|
- Test happy paths and error cases
|
|
- Test edge cases and boundary conditions
|
|
- Include table-driven tests for multiple scenarios
|
|
- Aim for >80% code coverage
|
|
|
|
### Benchmarks
|
|
Include benchmarks for performance-critical code:
|
|
```go
|
|
func BenchmarkFeature(b *testing.B) {
|
|
// setup
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
// code to benchmark
|
|
}
|
|
}
|
|
```
|
|
|
|
## Performance Guidelines
|
|
|
|
### Memory Management
|
|
- Reuse buffers where possible (sync.Pool for hot paths)
|
|
- Avoid unnecessary allocations in request handlers
|
|
- Use string builders for concatenation
|
|
- Pre-allocate slices with known capacity
|
|
|
|
### Concurrency
|
|
- All exported methods must be safe for concurrent use
|
|
- Use atomic operations for simple flags (e.g., IsShuttingDown)
|
|
- Document any concurrency requirements or limitations
|
|
- Test concurrent access with `-race` flag
|
|
|
|
## Documentation Standards
|
|
|
|
### README Updates
|
|
When adding features:
|
|
- Add to Table of Contents if new section
|
|
- Provide working code examples
|
|
- Show both basic and advanced usage
|
|
- Update Quick Start if core API changes
|
|
|
|
### Code Examples
|
|
- Must be runnable without modification
|
|
- Use realistic names and scenarios
|
|
- Include error handling
|
|
- Show best practices
|
|
|
|
## Common Patterns in This Project
|
|
|
|
### Handler Registration
|
|
```go
|
|
// Pattern: method + " " + pattern
|
|
path := fmt.Sprintf("%s %s", method, pattern)
|
|
m.mux.Handle(path, stack(h, m.middlewares))
|
|
m.routes.Add(path)
|
|
```
|
|
|
|
### Middleware Stacking
|
|
```go
|
|
// Stack middleware from slice, innermost handler first
|
|
handler := h
|
|
for i := len(middlewares) - 1; i >= 0; i-- {
|
|
handler = middlewares[i](handler)
|
|
}
|
|
```
|
|
|
|
### Suffix Path Building
|
|
```go
|
|
// Always ensure single "/" between components
|
|
if !strings.HasSuffix(base, "/") {
|
|
base += "/"
|
|
}
|
|
path := base + suffix
|
|
```
|
|
|
|
## Anti-Patterns to Avoid
|
|
|
|
❌ **Don't** use global variables
|
|
❌ **Don't** ignore errors without explicit comment
|
|
❌ **Don't** use naked returns in long functions
|
|
❌ **Don't** add external dependencies
|
|
❌ **Don't** use reflection
|
|
❌ **Don't** create goroutines without cleanup
|
|
❌ **Don't** use `interface{}` (use `any` in Go 1.18+)
|
|
❌ **Don't** allocate in hot paths unnecessarily
|
|
❌ **Don't** panic for runtime errors (use error returns)
|
|
|
|
## Commit Message Format
|
|
|
|
Use conventional commits:
|
|
- `feat:` - New feature
|
|
- `fix:` - Bug fix
|
|
- `docs:` - Documentation changes
|
|
- `test:` - Test additions/modifications
|
|
- `refactor:` - Code refactoring
|
|
- `perf:` - Performance improvements
|
|
- `chore:` - Maintenance tasks
|
|
|
|
Example: `feat: add MemberPOST and MemberGET methods to Resource`
|
|
|
|
## AI Assistant Guidelines
|
|
|
|
When generating code:
|
|
1. Run quality checks mentally (vet, staticcheck, fieldalignment)
|
|
2. Ensure proper nil checks on all methods
|
|
3. Add comments for all exported items
|
|
4. Follow existing naming patterns
|
|
5. Maintain zero external dependencies
|
|
6. Optimize for performance (zero allocs in hot paths)
|
|
7. Write concurrent-safe code
|
|
8. Include tests with new features
|
|
9. Update README.md if adding public APIs
|
|
10. Use Go 1.25+ features when appropriate
|
|
|
|
## Questions to Ask Before Coding
|
|
|
|
1. Does this maintain zero external dependencies?
|
|
2. Is this the simplest solution?
|
|
3. Will this pass go vet, staticcheck, and fieldalignment?
|
|
4. Is this safe for concurrent use?
|
|
5. Does this follow existing patterns?
|
|
6. Are all exported items documented?
|
|
7. Have I added tests?
|
|
8. Can this be optimized to reduce allocations?
|
|
|
|
---
|
|
|
|
Remember: Simplicity, performance, and maintainability are the core values of this project.
|