Middleware chain
- Go course
- Advanced
- Lesson 33/68
- 4 min
Learn to chain multiple middlewares.
Middleware chain
Middleware is wrapped inside each other to form a chain. The outermost runs first:
h := logla(yetki(api)) // request: logla → yetki → apiWith many middleware a readable helper is written:
func zincir(h http.Handler, mw ...func(http.Handler) http.Handler) http.Handler {
for i := len(mw) - 1; i >= 0; i-- {
h = mw[i](h)
}
return h
}
h := zincir(api, logla, yetki) // logla still firstWhy order matters
Recover middleware must be outermost so it catches every panic inside. If logging sits near the outside it records unauthorized requests too; inside the auth check it records only those that pass. The order is a design decision: zincir(api, recover, logla, yetki) is a common arrangement.
Practice Build a chain
Write harf(s string) func(http.Handler) http.Handler, which builds middleware that prints a letter. Send a request through h := harf("A")(harf("B")(son)); the son handler prints C.
Starter code
package main
import (
"fmt"
"net/http"
"net/http/httptest"
)
func main() {
// buraya yaz
}Sample solution
package main
import (
"fmt"
"net/http"
"net/http/httptest"
)
func harf(s string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println(s)
next.ServeHTTP(w, r)
})
}
}
func main() {
son := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Println("C") })
h := harf("A")(harf("B")(son))
h.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest("GET", "/", nil))
}Expected output
A B C
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 In the chain <code>a(b(c(h)))</code>, which runs first on the way in?
- b
- a Correct answer
- c
- h
Explanation: The outermost wrapper receives the request first; on the way out the order reverses.
2 Wrap from the end
for i := len(mw) - 1; i >= 0; i-- {
h = mw[____](h)
}
for i := len(mw) - 1; i >= 0; i-- {
h = mw[i](h)
}
Explanation: Wrapping the list from the end keeps the first-listed middleware outermost.
3 Position in the chain
| Term | Meaning |
|---|---|
Recover |
Outermost |
Log |
Near the outside |
Auth |
Near the handler |
api |
Innermost |