Go
HTTP middleware
func(http.Handler) http.Handler desenini öğrenirsin.
http.HandlerFunc ile sarmak
http.HandlerFunc, sıradan bir fonksiyonu http.Handler'a çeviren türdür. Middleware içinde kapanış (closure) olarak yeni işleyici oluşturmak için kullanılır:
func zamanla(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
bas := time.Now()
next.ServeHTTP(w, r)
log.Println(r.URL.Path, time.Since(bas))
})
}
next.ServeHTTP'tan önceki kod istek yolunda, sonraki kod yanıt yolunda çalışır.
Parametreli middleware
Ayar alan middleware, middleware döndüren bir fonksiyonla yazılır:
func header(ad, deger string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set(ad, deger)
next.ServeHTTP(w, r)
})
}
}
h := header("X-Surum", "2")(api)
Uygulama Önce ve sonra
izle(next http.Handler) http.Handler yaz: fmt.Println("önce"), next.ServeHTTP, sonra fmt.Println("sonra"). İşleyici fmt.Println("işleyici") yazdırsın; httptest ile bir istek gönder.
Örnek çözümü göster
package main
import (
"fmt"
"net/http"
"net/http/httptest"
)
func izle(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("önce")
next.ServeHTTP(w, r)
fmt.Println("sonra")
})
}
func main() {
h := izle(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("işleyici")
}))
h.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest("GET", "/", nil))
}
Kendini test et
-
Middleware <code>next.ServeHTTP</code> çağırmazsa ne olur?
- Sunucu çöker
- İstek iki kez işlenir
- Asıl işleyici çalışmaz; istek middleware'de biter
- Go otomatik çağırır
Cevabı göster
Asıl işleyici çalışmaz; istek middleware'de biter — Zinciri devam ettirmek middleware'in sorumluluğudur; çağırmamak isteği kesmek demektir (yetkisiz isteklerde bilerek yapılır).
-
Fonksiyonu işleyiciye çevir
return http.____(func(w http.ResponseWriter, r *http.Request) {
next.ServeHTTP(w, r)
})
Cevabı göster
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
next.ServeHTTP(w, r)
})
-
Çalışma sırası
- next öncesi
- İstek yolunda
- next.ServeHTTP
- Asıl işleyici
- next sonrası
- Yanıt yolunda
- return (next yok)
- İsteği keser
Sıradaki ders: Middleware zinciri