Summary - Middleware
- Go course
- Advanced
- Lesson 36/68
- 4 min
Combine logging and auth middlewares.
Middleware summary
Middleware = func(http.Handler) http.Handler. In this group you wrote wrappers with http.HandlerFunc, built parameterized middleware, saw how order matters in a chain, recorded the status code by wrapping ResponseWriter, and stopped unauthorized requests with 401.
h := zincir(api, recoverMW, logla, yetki)
http.ListenAndServe(":8080", h)Recover middleware
A panic in a handler doesn't bring down the whole server but cuts the connection. Recover middleware turns it into a 500 response:
func recoverMW(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if v := recover(); v != nil {
http.Error(w, "sunucu hatası", 500)
}
}()
next.ServeHTTP(w, r)
})
}Practice Recover middleware
Write recoverMW(next http.Handler) http.Handler: if a panic is caught with defer + recover(), write http.Error(w, "sunucu hatası", 500). Test with a handler that calls panic("x") and print rec.Code.
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 recoverMW(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if v := recover(); v != nil {
http.Error(w, "sunucu hatası", 500)
}
}()
next.ServeHTTP(w, r)
})
}
func main() {
h := recoverMW(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { panic("x") }))
rec := httptest.NewRecorder()
h.ServeHTTP(rec, httptest.NewRequest("GET", "/", nil))
fmt.Println(rec.Code)
}Expected output
500
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Where should panic-catching recover middleware be in the chain?
- After auth
- It doesn't matter
- Outermost Correct answer
- Innermost
Explanation: recover only catches panics in code running inside it; outermost, it protects the whole chain.
2 Catch the panic
defer func() {
if v := ____(); v != nil {
http.Error(w, "hata", 500)
}
}()
defer func() {
if v := recover(); v != nil {
http.Error(w, "hata", 500)
}
}()
Explanation: recover, inside a defer, stops an ongoing panic and returns its value.
3 Middleware and role
| Term | Meaning |
|---|---|
recoverMW |
Panic → 500 |
logla |
Path, code, duration |
yetki |
Credentials → 401 |
zincir |
Wraps in order |