Middleware
Neutron Go middleware uses the standard func(http.Handler) http.Handler signature, compatible with the entire net/http ecosystem.
Built-In Middleware
app := neutron.New(
neutron.WithMiddleware(
neutron.Logger(logger), // Structured logging
neutron.Recover(), // Panic recovery
neutron.RequestID(), // X-Request-ID
neutron.CORS(neutron.CORSOptions{ // CORS headers
AllowOrigins: []string{"https://example.com"},
AllowMethods: []string{"GET", "POST"},
AllowHeaders: []string{"Authorization"},
AllowCredentials: true,
MaxAge: 3600,
}),
neutron.RateLimit(100, 1000), // 100 RPS, burst 1000
neutron.Timeout(30 * time.Second), // Request timeout
neutron.Compress(gzip.DefaultCompression), // Gzip compression
neutron.OTel(neutron.OTelOptions{ // OpenTelemetry
ServiceName: "my-api",
}),
),
)
| Middleware | Description |
|-----------|-------------|
| Logger | Method, path, status, duration, request_id |
| Recover | Catches panics, returns 500 |
| RequestID | Generates X-Request-Id header |
| CORS | Cross-origin resource sharing |
| RateLimit | Token bucket rate limiting |
| Timeout | Per-request deadline |
| Compress | Gzip response compression |
| OTel | OpenTelemetry trace context |
Custom Middleware
func TimingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
w.Header().Set("X-Response-Time",
fmt.Sprintf("%dms", time.Since(start).Milliseconds()))
})
}
app := neutron.New(
neutron.WithMiddleware(TimingMiddleware),
)
Scoped Middleware
Apply middleware to specific route groups:
// Public routes — no auth
public := router.Group("/public")
// API routes — JWT required
api := router.Group("/api",
neutronauth.JWTMiddleware(secret),
)
// Admin routes — JWT + RBAC
admin := router.Group("/admin",
neutronauth.JWTMiddleware(secret),
neutronauth.RBACMiddleware("admin"),
)
Composing Middleware
authStack := neutron.Chain(
neutronauth.JWTMiddleware(secret),
neutronauth.RBACMiddleware("admin"),
)
admin := router.Group("/admin", authStack)
Context Values
Access middleware-injected values:
func handler(ctx context.Context, _ neutron.Empty) (string, error) {
requestID := neutron.RequestIDFromContext(ctx)
traceID := neutron.TraceIDFromContext(ctx)
return fmt.Sprintf("request=%s trace=%s", requestID, traceID), nil
}