Menu
Coddy logo textTech

http.Handler Arayüzü

Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 77 / 107.

http.Handler arayüzü, Go'nun web sunucusu mimarisinin temelidir. HTTP isteklerinin nasıl işlendiğini tanımlar ve bunu uygulayan herhangi bir tür web isteklerine hizmet verebilir.

Arayüz oldukça basittir:

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

ServeHTTP metoduna sahip herhangi bir tür, HTTP isteklerini işleyebilir. İşte özel bir işleyici:

type GreetHandler struct {
    Greeting string
}

func (h GreetHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "%s, visitor!", h.Greeting)
}

Bu işleyiciyi doğrudan bir sunucuyla kullanabilirsiniz:

handler := GreetHandler{Greeting: "Welcome"}
http.Handle("/greet", handler)

Daha basit durumlar için Go, normal bir fonksiyonu bir işleyiciye (handler) dönüştürmenize olanak tanıyan bir tür olan http.HandlerFunc sağlar:

func hello(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello!")
}

http.Handle("/hello", http.HandlerFunc(hello))

İşleyicilerin (handlers) diğer işleyicileri sarmalayabildiğini fark ettiğinizde bu arayüzün gücü netleşir. Bu, orijinal işleyici mantığını değiştirmeden günlükleme (logging), kimlik doğrulama (authentication) veya diğer çapraz kesen ilgileri (cross-cutting concerns) eklediğiniz ara yazılım (middleware) desenlerini mümkün kılar.

challenge icon

Görev

Kolay

Web isteklerinin nasıl işlendiğini simüle eden basit bir HTTP işleyici (handler) sistemi kuralım! Bu ortamda gerçek bir HTTP sunucusu çalıştıramadığımız için, http.Handler arayüzünü (interface) uygulayan işleyiciler oluşturacak ve sahte (mock) istek/yanıt nesneleriyle çalışarak bunların istekleri nasıl işlediğini göstereceksiniz.

Kodunuzu iki dosya halinde düzenleyeceksiniz:

  • handlers.go: Özel HTTP işleyicilerinizi tanımlayın.

    Bir HTTP yanıtına ne yazılacağını yakalayan bir MockResponseWriter yapısı (struct) oluşturun. Yanıt gövdesini bir dize (string) olarak saklamalı ve gövdeye veri ekleyen bir Write(data []byte) (int, error) yöntemi uygulamalıdır. Biriken yanıtı almak için bir Body() string yöntemi ekleyin.

    Bir HTTP isteğini simüle etmek için Path ve Method dize alanlarına sahip bir MockRequest yapısı oluşturun.

    Şimdi http.Handler arayüz desenini uygulayan (bir *MockResponseWriter ve *MockRequest alan bir ServeHTTP yöntemine sahip) iki işleyici yapısı oluşturun:

    • Message alanına sahip WelcomeHandler - mesajı ve ardından istek yolunu yazar
    • MethodHandler - istek yöntemine göre farklı yanıtlar yazar: GET için "Fetching data", POST için "Creating resource" ve diğer her şey için "Method not supported"
  • main.go: İstekleri işleyicileriniz aracılığıyla işleyin.

    Bir işleyici türü (welcome veya method) okuyun, ardından istek ayrıntılarını okuyun. Welcome işleyicisi için karşılama mesajını da okuyun.

    Uygun işleyiciyi oluşturun, sahte bir istek oluşturun ve işlemek için ServeHTTP yöntemini çağırın. Yanıt gövdesini yazdırın.

Aşağıdaki girdiler sağlanacaktır:

  • Satır 1: İşleyici türü (welcome veya method)
  • Satır 2: İstek yolu (path)
  • Satır 3: İstek yöntemi (method)
  • Satır 4 (yalnızca welcome için): Karşılama mesajı

Örneğin, şu girdi verildiğinde:

welcome
/home
GET
Hello from

Çıktınız şu olmalıdır:

Hello from /home

Ve şu girdi verildiğinde:

method
/api/users
POST

Çıktınız şu olmalıdır:

Creating resource

Ve şu girdi verildiğinde:

method
/api/data
GET

Çıktınız şu olmalıdır:

Fetching data

Ve şu girdi verildiğinde:

method
/api/items
DELETE

Çıktınız şu olmalıdır:

Method not supported

Bu zorluk, http.Handler arayüzünün temel kavramını gösterir; ServeHTTP yöntemine sahip herhangi bir tür istekleri işleyebilir. Gerçek uygulamalarda, http.ResponseWriter ve *http.Request Go'nun standart kütüphanesinden gelir, ancak işleyicileri uygulama deseni tamamen aynı kalır.

Kopya kağıdı

http.Handler arayüzü, Go'nun web sunucusu mimarisinin temelidir:

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

ServeHTTP metoduna sahip herhangi bir tür, HTTP isteklerini işleyebilir:

type GreetHandler struct {
    Greeting string
}

func (h GreetHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "%s, visitor!", h.Greeting)
}

Sunucuya bir işleyici (handler) kaydedin:

handler := GreetHandler{Greeting: "Welcome"}
http.Handle("/greet", handler)

Daha basit durumlar için, bir fonksiyonu işleyiciye dönüştürmek üzere http.HandlerFunc kullanın:

func hello(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello!")
}

http.Handle("/hello", http.HandlerFunc(hello))

İşleyiciler diğer işleyicileri sarmalayabilir; bu da günlükleme (logging), kimlik doğrulama (authentication) veya diğer çapraz kesen ilgiler (cross-cutting concerns) için ara yazılım (middleware) desenlerini mümkün kılar.

Kendin dene

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// İşleyici türünü oku
	scanner.Scan()
	handlerType := scanner.Text()
	
	// İstek yolunu oku
	scanner.Scan()
	path := scanner.Text()
	
	// İstek yöntemini oku
	scanner.Scan()
	method := scanner.Text()
	
	// Sahte istek oluştur
	request := &MockRequest{
		Path:   path,
		Method: method,
	}
	
	// Sahte yanıt yazıcısı oluştur
	response := &MockResponseWriter{}
	
	// TODO: handlerType'a bağlı olarak uygun işleyiciyi oluşturun
	// Eğer handlerType "welcome" ise, karşılama mesajını okuyun ve WelcomeHandler oluşturun
	// Eğer handlerType "method" ise, MethodHandler oluşturun
	// İşleyici üzerinde response ve request ile ServeHTTP'yi çağırın
	
	if handlerType == "welcome" {
		scanner.Scan()
		message := scanner.Text()
		// TODO: Mesaj ile WelcomeHandler oluşturun ve ServeHTTP'yi çağırın
		_ = message // Uygularken bu satırı kaldırın
	} else if handlerType == "method" {
		// TODO: MethodHandler oluşturun ve ServeHTTP'yi çağırın
	}
	
	// Yanıt gövdesini yazdır
	fmt.Println(response.Body())
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler