Chapter 10: Middleware
This is one of the most advanced concepts in Go web servers. Let's dissect it carefully.
1 Functions as Values
In Go, a function is a value. You can:
- Store it in a variable.
- Pass it as an argument.
- Return it from another function.
2 The Middleware Signature
go
func Logging(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Pre-Processing
fmt.Println("Start")
next.ServeHTTP(w, r) // Pass the baton
// Post-Processing
fmt.Println("End")
})
}Line-by-Line Anatomy
func Logging(next http.Handler) http.Handler:- Input: The Next layer of the onion (the inner handler).
- Output: A New handler that wraps the old one.
return http.HandlerFunc(...):- We are building a new handler on the fly.
func(w, r):- This is the Closure. It captures the
nextvariable from outside.
- This is the Closure. It captures the
next.ServeHTTP(w, r):- Crucial: This calls the original handler.
- If you forget this line, the request stops here. The User never gets a response.
If Transport talks to Service, and Service talks to Repository... who checks if the user is logged in? Who measures speed? This is the Middleware.
3 The Matryoshka (Russian Doll)
Middleware is like a Matryoshka doll. You put your Handler inside a Logger. You put the Logger inside an Authenticator. When a request comes in, it has to drill through all the outer layers to reach the center (your logic).
The Chain
When we wrap handlers: Logging(Auth(HomeHandler))
- Request arrives $\rightarrow$ Logging starts.
- Logging calls
next$\rightarrow$ Auth starts. - Auth calls
next$\rightarrow$ HomeHandler (Business Logic). - HomeHandler returns.
- Auth finishes.
- Logging finishes.
🎓 Knowledge Check: What happens if a middleware forgets to call next.ServeHTTP(w, r)?
Answer: The request stops there! It never reaches the next middleware or your business logic. The user will likely see a blank screen or a timeout.
