0Pricing
Go Academy · Lesson

Middleware Pattern

Chaining handlers for logging and auth

Middleware Pattern is a free Go Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What is middleware?

Middleware is a function that wraps an http.Handler to add cross-cutting behaviour (logging, auth, recovery) without modifying the handler's business logic.

Middleware signature

A middleware is a function that takes an http.Handler and returns an http.Handler:

type Middleware func(http.Handler) http.Handler

Simple logging middleware

Log each request before and after the handler runs:

func Logger(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Printf("%s %s", r.Method, r.URL.Path)
        next.ServeHTTP(w, r)
        log.Printf("done %s", r.URL.Path)
    })
}

Chaining middleware

Apply multiple middleware layers by nesting them:

handler := Logger(Auth(RateLimit(myHandler)))
http.ListenAndServe(":8080", handler)

Middleware chain helper

Build a chain function to apply middleware in order without deep nesting:

func Chain(h http.Handler, m ...Middleware) http.Handler {
    for i := len(m)-1; i >= 0; i-- {
        h = m[i](h)
    }
    return h
}
// Usage: Chain(myHandler, Logger, Auth, RateLimit)

Auth middleware

Check authentication before calling the next handler. Return 401 early if the token is missing or invalid.

func Auth(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        token := r.Header.Get("Authorization")
        if !isValid(token) {
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return
        }
        next.ServeHTTP(w, r)
    })
}

Panic recovery middleware

Catch panics from handlers so the server doesn't crash:

func Recovery(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        defer func() {
            if err := recover(); err != nil {
                log.Printf("panic: %v", err)
                http.Error(w, "Internal Server Error", 500)
            }
        }()
        next.ServeHTTP(w, r)
    })
}

Passing data via context

Middleware can attach data to the request context for downstream handlers:

ctx := context.WithValue(r.Context(), userKey, user)
next.ServeHTTP(w, r.WithContext(ctx))

Response wrapper

Capture the status code written by the handler by wrapping ResponseWriter:

type statusRecorder struct {
    http.ResponseWriter
    status int
}
func (r *statusRecorder) WriteHeader(code int) {
    r.status = code
    r.ResponseWriter.WriteHeader(code)
}

Order matters

Middleware executes in the order it wraps the handler. Auth should run before rate limiting; panic recovery should be outermost so it catches panics from other middleware.

Per-route vs global middleware

Apply global middleware (logging, recovery) to the entire mux. Apply route-specific middleware (auth, rate limit) to specific route groups using a subrouter or handler wrapper.

Quick Check

What is the correct signature for an HTTP middleware in Go?

Recap: Middleware Pattern

Key points:

  • Middleware: func(http.Handler) http.Handler
  • Chain by nesting; use a Chain helper for clarity
  • Recovery outermost; Auth before business logic
  • Pass data downstream via context

Frequently asked questions

Is the “Middleware Pattern” lesson free?

Yes — the full text of “Middleware Pattern” is free to read here on the web, and the Go Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Go Academy course, upgrade to CoddyKit PRO.

What will I learn in “Middleware Pattern”?

Chaining handlers for logging and auth You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Go Academy?

No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Middleware Pattern” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Go Academy lesson?

Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Creating an HTTP Server
  2. Routing and Path Parameters
  3. Middleware Pattern
  4. Graceful Shutdown
← Back to Go Academy