Middleware
Learn Kern middleware for Go API servers, including global middleware, route-specific middleware, request flow ordering, and custom middleware patterns.
Middleware Concept
Middleware in Kern allows you to intercept requests before they reach your route handler. It follows the standard Go func(http.Handler) http.Handler pattern, making it seamlessly compatible with the vast ecosystem of existing Go middleware libraries.
Middleware is executed in the order it is added ("onion" model).
If you are building a Go API server, middleware is where you centralize cross-cutting concerns such as logging, authentication, request IDs, CORS, rate limits, request guards, and response policies.
Global Middleware
To add middleware that runs for every request hitting your application, use app.Use().
app := kern.New()
app.Use(kern.Logger())
app.Use(kern.Recovery())
app.Use(kern.CORS([]string{"*"}))Group Middleware
You can apply middleware to specific groups of routes. This is perfect for authentication or area-specific logic.
api := app.Group("/api")
// Only /api/* routes will run this middleware
api.Use(authMiddleware)
// or apply inline when creating a group:
admin := app.Group("/admin", adminAuthMiddleware, auditLogMiddleware)Built-in Middleware
Kern comes with essential middleware out of the box to get you started quickly.
Logger
Logs incoming requests with their method, path, status code, duration, and response size.
app.Use(kern.Logger())Example output:
[GET] /users 127.0.0.1:54321 - 200 (150µs) 450 bytesRecovery
Catches any panics that occur during request handling, logs the stack trace, and sends a 500 Internal Server Error to the client. This ensures your server stays running even if a handler crashes.
app.Use(kern.Recovery())It is highly recommended to include Recovery middleware in production.
CORS (Cross-Origin Resource Sharing)
Handles CORS preflight requests and headers transparently.
// Allow specific origins
app.Use(kern.CORS([]string{"https://example.com", "https://app.example.com"}))
// Allow all origins (use with caution in production)
app.Use(kern.CORS([]string{"*"}))For advanced configuration:
app.Use(kern.CORSWithConfig(kern.CORSConfig{
AllowOrigins: []string{"https://example.com"},
AllowMethods: []string{"GET", "POST", "PUT", "DELETE"},
AllowHeaders: []string{"Content-Type", "Authorization"},
ExposeHeaders: []string{"X-Request-ID"},
AllowCredentials: true,
MaxAge: 86400,
}))RequestID
Generates and tracks a unique request ID for each request. Useful for debugging and logging:
import "github.com/mobentum/kern/middleware"
app.Use(middleware.RequestID())The middleware:
- Generates a 128-bit random ID if not provided
- Reuses incoming
X-Request-IDheader if present - Sets the ID in response header
X-Request-ID - Stores it in request context for access in handlers
Choosing middleware placement
- Use app-global middleware for logging, panic recovery, CORS, security defaults, and request IDs.
- Use group middleware for protected surfaces such as
/apior/admin. - Use route-level middleware for strict request validation, body limits, and response limits on selected endpoints.
Middleware Guides
Core middleware:
Optional middleware package:
- RequestID
- Gzip
- Timeout
- RateLimiter
- JWT
- CSRF
- SecurityHeaders
- HeaderLimits
- RequestGuard
- ResponseLimit
- Session
Custom Middleware
Writing custom middleware is simple. It just needs to return a function that wraps an http.Handler.
kern.MiddlewareFunc is an alias for func(http.Handler) http.Handler.
Example: Simple Auth Middleware
func AuthRequired() kern.MiddlewareFunc {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
// Validate token
if token != "secret-token" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return // Stop the chain, do not call next
}
// Continue to the next handler
next.ServeHTTP(w, r)
})
}
}Example: Response Header Middleware
func PoweredBy() kern.MiddlewareFunc {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Powered-By", "kern Framework")
next.ServeHTTP(w, r)
})
}
}See Also
- Middleware Example - Complete middleware patterns
- Middleware Catalog - First-party middleware reference
- Migration Guide - Adoption guidance for new middleware and routing features
- Architecture Flow - Understand how middleware wraps routing and response writes
FAQ
In what order does Kern execute middleware?
Middleware runs in the order it is registered, with the first middleware acting as the outermost wrapper around later middleware and the final route handler.
Should I apply everything globally?
No. Keep global middleware focused on broad concerns and apply strict policies such as RequestGuard and ResponseLimit only to the routes that need them.
Context API
Learn the Kern Context API for Go request parsing, response writing, file uploads, downloads, headers, cookies, and efficient pooled request handling.
Middleware Catalog
Complete middleware catalog for Kern, covering built-in Go HTTP middleware, optional first-party middleware, request guards, sessions, rate limiting, and response controls.