Create HTTP middleware chain in Go
✓Works with OpenClaudeYou are a Go backend developer. The user wants to create a reusable HTTP middleware chain in Go that can wrap handlers, log requests, validate tokens, and compose multiple middleware functions.
What to check first
- Verify Go is installed:
go version - Check that
net/httpis available (standard library — always present) - Understand your middleware ordering — earlier middleware wraps outer, executes first on request
Steps
- Define a middleware type as
func(http.Handler) http.Handler— this signature allows chaining - Create individual middleware functions that accept an
http.Handlerand return anhttp.Handler - Inside each middleware, write the logic before
next.ServeHTTP(w, r)for pre-processing (request side) - Write logic after
next.ServeHTTP(w, r)for post-processing (response side) - Build a chain helper function that applies middleware in correct order using function composition
- Register your final chained handler with
http.HandleFunc()orhttp.Handle() - Test the execution order by adding log statements in each middleware layer
- Apply middleware selectively to routes or globally depending on your multiplexer
Code
package main
import (
"fmt"
"log"
"net/http"
"time"
)
// Middleware is the type for HTTP middleware functions
type Middleware func(http.Handler) http.Handler
// LoggingMiddleware logs request details and response time
func LoggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
log.Printf("→ %s %s", r.Method, r.URL.Path)
next.ServeHTTP(w, r)
log.Printf("← %s %s (%v)", r.Method, r.URL.Path, time.Since(start))
})
}
// AuthMiddleware validates Bearer token in Authorization header
func AuthMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
if token == "" {
http.Error(w, "Missing authorization token", http.StatusUnauthorized)
return
}
if token != "Bearer valid-token-123" {
http.Error(w, "Invalid token", http.StatusForbidden)
return
}
next.ServeHTTP(w, r)
})
}
// PanicRecoveryMiddleware catches panics and returns 500 error
func PanicRecoveryMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err !=
Note: this example was truncated in the source. See the GitHub repo for the latest full version.
Common Pitfalls
- Treating this skill as a one-shot solution — most workflows need iteration and verification
- Skipping the verification steps — you don't know it worked until you measure
- Applying this skill without understanding the underlying problem — read the related docs first
When NOT to Use This Skill
- When a simpler manual approach would take less than 10 minutes
- On critical production systems without testing in staging first
- When you don't have permission or authorization to make these changes
How to Verify It Worked
- Run the verification steps documented above
- Compare the output against your expected baseline
- Check logs for any warnings or errors — silent failures are the worst kind
Production Considerations
- Test in staging before deploying to production
- Have a rollback plan — every change should be reversible
- Monitor the affected systems for at least 24 hours after the change
Related Go Skills
Other Claude Code skills in the same category — free to download.
Go API Setup
Scaffold Go REST API with Gin or Chi router
Go Testing
Set up Go testing with table-driven tests and mocks
Go Modules
Manage Go modules and dependency versioning
Go Concurrency
Implement goroutines, channels, and concurrency patterns
Go Docker
Create optimized multi-stage Docker build for Go apps
Go gRPC
Set up gRPC server and client in Go
Go CLI
Build CLI applications with Cobra in Go
Want a Go skill personalized to YOUR project?
This is a generic skill that works for everyone. Our AI can generate one tailored to your exact tech stack, naming conventions, folder structure, and coding patterns — with 3x more detail.