CodeBlanks Logo Icon CodeBlanks

http.Handler

Handler interface'ini ve ServeHTTP öğrenirsin.

http.Handler

Sunucu tarafının merkezinde tek yöntemli bir arayüz vardır:

type Handler interface {
    ServeHTTP(w http.ResponseWriter, r *http.Request)
}

r istekle ilgili her şeyi (yöntem, yol, başlıklar, gövde, context) taşır; w ile durum kodu, başlık ve gövde yazılır. ServeHTTP yöntemi olan her tür bir işleyicidir; bu yüzden durum tutan işleyiciler struct olarak yazılabilir.

Durum tutan işleyici

Bağımlılıkları (veritabanı, logger, ayarlar) alan bir struct işleyici, global değişkenlerden kaçınmayı sağlar:

type SayacHandler struct {
    mu sync.Mutex
    n  int
}

func (h *SayacHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    h.mu.Lock()
    h.n++
    n := h.n
    h.mu.Unlock()
    fmt.Fprintf(w, "ziyaret: %d", n)
}

Sunucu her isteği ayrı goroutine'de işlediği için paylaşılan durum kilitle korunur.

Uygulama Struct işleyici

Yukarıdaki SayacHandler'ı yaz. httptest.NewRecorder ile aynı işleyiciye iki istek gönder ve ikinci yanıtın gövdesini yazdır.

Başlangıç kodu

main.go
package main

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

func main() {
    // buraya yaz
}

Örnek çözüm

main.go
package main

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

type SayacHandler struct {
    mu sync.Mutex
    n  int
}

func (h *SayacHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    h.mu.Lock()
    h.n++
    n := h.n
    h.mu.Unlock()
    fmt.Fprintf(w, "ziyaret: %d", n)
}

func main() {
    h := &SayacHandler{}
    h.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest("GET", "/", nil))
    rec := httptest.NewRecorder()
    h.ServeHTTP(rec, httptest.NewRequest("GET", "/", nil))
    fmt.Println(rec.Body.String())
}

Beklenen çıktı

ziyaret: 2

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Yanıtta başlık ayarlamak için doğru sıra hangisidir?

  • Header().Set → WriteHeader → Write Doğru cevap
  • Write → Header().Set
  • WriteHeader → Header().Set → Write
  • Sıra önemli değildir

Açıklama: WriteHeader (ya da ilk Write) başlıkları gönderir; sonrasında yapılan Header().Set değişiklikleri etkisizdir.

2 Arayüz yöntemi

Soru
func (h *Api) ____(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("ok"))
}
Cevap
func (h *Api) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("ok"))
}

Açıklama: ServeHTTP yöntemi olan her tür http.Handler arayüzünü karşılar.

3 İstek alanı

Kavram Anlamı
r.Method GET, POST...
r.URL.Path Yol
r.Header Başlıklar
r.Context() İptal ve değerler

Orta seviye bölümündeki tüm dersler