CodeBlanks Logo Icon CodeBlanks

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

main.go
package main

import (
    "fmt"
    "net/http"
    "net/http/httptest"
)

func main() {
    // buraya yaz
}

Örnek çözüm

main.go
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

Soru
return http.____(func(w http.ResponseWriter, r *http.Request) {
    next.ServeHTTP(w, r)
})
Cevap
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

İleri seviye bölümündeki tüm dersler