# Middleware in the Application
Middleware in this application provides a way to intercept and process HTTP requests before they reach the final handler. Each middleware serves a specific purpose, such as authentication, session management, or request modification.
# Types of Middleware
# 1. Preview Middleware
File: /internal/middlewares/preview_middleware.go
Purpose:
The Preview Middleware enables temporary preview functionality for administrators and developers, allowing them to render game content without affecting the live game.
Key Features:
- Detects HTMX preview requests from admin or template pages
- Creates a temporary team instance with a preview context
- Sets a short-lived game instance (1 hour duration), overriding the active instance
Usage Example:
middleware := PreviewMiddleware(teamService, nextHandler)
# 2. Team Middleware
File: /internal/middlewares/team_middleware.go
Purpose:
The Team Middleware extracts team information from the session and loads the associated game instance.
Key Features:
- Retrieves team code from the session
- Loads team and instance relationships
- Adds team context to the request
Usage Example:
middleware := TeamMiddleware(teamService, nextHandler)
# 3. Lobby Middleware
File: /internal/middlewares/lobby_middleware.go
Purpose:
The Lobby Middleware manages team access based on the game instance status, redirecting users to the lobby when necessary.
Key Features:
- Checks game instance status
- Redirects to lobby for inactive game instances
- Adds team context to the request
Usage Example:
middleware := LobbyMiddleware(teamService, nextHandler)
# 4. Admin Authentication Middleware
File: admin.go
Purpose:
Manages authentication and authorization for administrative routes.
Key Features:
- Verifies user authentication
- Checks email verification status
- Ensures users have selected an instance for admin actions
Usage Example:
middleware := AdminAuthMiddleware(authService, nextHandler)
middleware := AdminCheckInstanceMiddleware(nextHandler)
# 5. Text HTML Middleware
File: /internal/middlewares/middleware.go
Purpose:
A simple middleware to set the content type for responses.
Key Features:
- Sets
Content-Type
header totext/html
Usage Example:
middleware := TextHTMLMiddleware(nextHandler)
# Best Practices
- Chaining Middleware: Use multiple middlewares in a chain to modularise request processing.
- Preview Middleware must be the first middleware in the chain when used.
- Context Management: Utilise request context to pass additional information between middlewares.
- Use the internal
contextkeys
package for context keys.
- Use the internal
- Performance: Keep middleware logic lightweight and efficient.
# Common Patterns
# Adding Team to Context
ctx := context.WithValue(r.Context(), contextkeys.TeamKey, team)
next.ServeHTTP(w, r.WithContext(ctx))
# Passing Through Non-Matching Requests
if !matchingCondition {
next.ServeHTTP(w, r)
return
}
# Extending Middleware
To create a new middleware:
- Define a function that takes a
next http.Handler
- Return a new
http.Handler
- Implement request interception logic
- Call
next.ServeHTTP()
to continue the request chain
# Testing
Middleware can be tested by:
- Mocking services
- Creating test requests
- Verifying context modifications
- Checking response behaviours
Refer to internal/middlewares/preview_middleware_test.go
for example tests.