HTTP middleware
- Go kursu
- İleri seviye
- Ders 32/68
- 4 dk
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.
Başlangıç kodu
package main
import (
"fmt"
"net/http"
"net/http/httptest"
)
func main() {
// buraya yaz
}Örnek çözüm
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))
}Beklenen çıktı
önce işleyici sonra
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 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 Doğru cevap
- Go otomatik çağırır
Açıklama: Zinciri devam ettirmek middleware'in sorumluluğudur; çağırmamak isteği kesmek demektir (yetkisiz isteklerde bilerek yapılır).
2 Fonksiyonu işleyiciye çevir
return http.____(func(w http.ResponseWriter, r *http.Request) {
next.ServeHTTP(w, r)
})
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
next.ServeHTTP(w, r)
})
Açıklama: http.HandlerFunc, imzası uyan fonksiyonu Handler arayüzünü karşılayan türe çevirir.
3 Çalışma sırası
| Kavram | Anlamı |
|---|---|
next öncesi |
İstek yolunda |
next.ServeHTTP |
Asıl işleyici |
next sonrası |
Yanıt yolunda |
return (next yok) |
İsteği keser |