High-Level Architecture
Showdown Trivia is built as a real-time multiplayer trivia game using Go, following a clean architecture pattern with clear separation of concerns. The system consists of several key layers:Component Breakdown
The application is initialized incmd/web/main.go:18 and follows this startup sequence:
1. Configuration Layer
Package:internal/config
Loads environment variables and validates configuration:
PORT: HTTP server portDB_URL: MongoDB connection stringLOG_LEVEL: Logging verbosity (debug, info, warn, error)ENV: Environment mode (dev/prod)
Configuration loading code
Configuration loading code
2. Repository Layer
Package:internal/repository
Handles all database operations using MongoDB:
- Connection management with connection pooling
- User repository with unique indexes on username and email
- Graceful disconnection with timeout
store.go:18- Database initializationstore.go:42- Store creation with indexesuser.go- User data access operations
The repository layer uses MongoDB with unique indexes to enforce data integrity at the database level.
3. Core Services Layer
Package:internal/core
Contains business logic organized into domain services:
User Service
Location:internal/core/user/service.go
Manages user operations:
- User retrieval and authentication
- User registration
- User deletion
Question Service
Location:internal/core/question/service.go
Fetches trivia questions:
- Retrieves questions from external Trivia API
- Fetches available categories
- Delegates to trivia API client
Game Service
Location:internal/core/game/game.go
Core game logic (detailed in Game Engine):
- Question flow management
- Answer collection via channels
- Scoring and winner calculation
- Timer-based progression
4. External API Client
Package:internal/trivia_api
Location: trivia_api.go:37
Integrates with OpenTDB for trivia questions:
- Fetches multiple-choice questions by category
- Retrieves available categories
- Shuffles answer options randomly
- Error handling for API responses
5. Web Layer
Package:internal/web
App Structure
Location:web/app.go:23
The main application struct coordinates all components:
HTTP Server
Location:web/app.go:53
Configured with:
- Read timeout: 10 seconds
- Write timeout: 30 seconds
- Idle timeout: 1 minute
- Graceful shutdown on SIGINT/SIGTERM
6. WebSocket Hub
Package:internal/web/ws
Location: ws/hub.go:27
Manages real-time game rooms and connections (detailed in WebSocket System):
- Room creation and lifecycle
- Client connection management
- Message broadcasting
- Metrics tracking
7. Middleware
Location:web/middleware.go
Provides cross-cutting concerns:
Available middleware
Available middleware
Authentication (
requireAuth:12)- Session validation
- Username extraction from session
- Redirect to signin if unauthorized
recoverPanic:30)- Catches panics in handlers
- Logs errors
- Prevents server crashes
requestDuration:45)- Prometheus metrics collection
- Tracks request timing by HTTP method
Request Flow
Standard HTTP Request Flow
WebSocket Request Flow
WebSocket connections are upgraded from HTTP requests and managed by separate goroutines for concurrent read/write operations.
Technology Stack
Core Technologies
| Component | Technology | Purpose |
|---|---|---|
| Language | Go 1.x | Server implementation |
| HTTP Server | net/http | Standard library HTTP server |
| Router | http.ServeMux | Request routing |
| WebSocket | gorilla/websocket | Real-time communication |
| Database | MongoDB | User data persistence |
| Sessions | gorilla/sessions | Cookie-based sessions |
| Templates | templ | Type-safe HTML templates |
| Logging | log/slog | Structured logging |
| Metrics | Prometheus | Application monitoring |
External Services
- OpenTDB API - Trivia question provider
- MongoDB Atlas (optional) - Cloud database hosting
Key Design Patterns
Clean Architecture
Clean Architecture
The codebase follows clean architecture principles:
- Core domain is independent of external concerns
- Service interfaces enable dependency injection
- Repository pattern abstracts data access
- Use cases defined in service layer
Concurrency Patterns
Concurrency Patterns
Go concurrency is used extensively:
- Goroutines for WebSocket read/write loops
- Channels for game events and answer collection
- Mutexes (RWMutex) for thread-safe access to shared state
- Select statements for multiplexing channel operations
Event-Driven Architecture
Event-Driven Architecture
Game events flow through channels:
- Game emits messages to
Messagechannel - Clients listen on egress channels
- Answers sent via
AnswerChchannel - Non-blocking event distribution
Routes Overview
Location:web/routes.go:15
Public Routes
GET /signin- Sign in pagePOST /signin- AuthenticationGET /signup- Registration pagePOST /signup- User registrationGET /static/*- Static assetsGET /metrics- Prometheus metrics
Protected Routes (require authentication)
GET /home- User dashboardGET /create- Game creation formPOST /create- Create gameGET /join/{id}- Join game pagePOST /signout- Sign out/activegames- List active games (HTMX)
WebSocket Endpoints
/wscreate- Create game room with WebSocket/wsjoin/{id}- Join existing room via WebSocket
All WebSocket endpoints require authentication and upgrade HTTP connections to WebSocket protocol.
Deployment Considerations
Environment Variables
Graceful Shutdown
The server implements graceful shutdown (web/app.go:63):
- Listens for SIGINT/SIGTERM signals
- 5-second timeout for existing connections
- Closes database connections cleanly
- Logs shutdown events
Monitoring
Prometheus metrics exposed at/metrics include:
- Active WebSocket connections
- Request duration by method
- Custom game metrics
Next Steps
WebSocket System
Deep dive into real-time communication architecture
Game Engine
Understand game logic and state management