Menu
Coddy logo textTech

http.Handler Interface

Teil des Abschnitts Objektorientierte Programmierung der GO-Journey von Coddy — Lektion 77 von 107.

Das http.Handler-Interface ist die Grundlage der Webserver-Architektur von Go. Es definiert, wie HTTP-Anfragen verarbeitet werden, und jeder Typ, der es implementiert, kann Web-Anfragen bedienen.

Die Schnittstelle ist bemerkenswert einfach:

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

Jeder Typ mit einer ServeHTTP-Methode kann HTTP-Anfragen verarbeiten. Hier ist ein benutzerdefinierter Handler:

type GreetHandler struct {
    Greeting string
}

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

Sie können diesen Handler direkt mit einem Server verwenden:

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

Für einfachere Fälle bietet Go http.HandlerFunc an, einen Typ, mit dem Sie eine reguläre Funktion in einen Handler konvertieren können:

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

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

Die Stärke dieser Schnittstelle wird deutlich, wenn man erkennt, dass Handler andere Handler umschließen können. Dies ermöglicht Middleware-Muster, bei denen Sie Logging, Authentifizierung oder andere querschnittliche Belange hinzufügen, ohne die ursprüngliche Handler-Logik zu ändern.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein einfaches HTTP-Handler-System bauen, das simuliert, wie Web-Anfragen verarbeitet werden! Da wir in dieser Umgebung keinen tatsächlichen HTTP-Server ausführen können, erstellen Sie Handler, die das http.Handler-Interface implementieren und demonstrieren, wie sie Anfragen verarbeiten, indem sie mit Mock-Request/Response-Objekten arbeiten.

Sie werden Ihren Code über zwei Dateien organisieren:

  • handlers.go: Definieren Sie Ihre benutzerdefinierten HTTP-Handler.

    Erstellen Sie ein MockResponseWriter-Struct, das erfasst, was in eine HTTP-Antwort geschrieben würde. Es sollte den Antwortkörper als String speichern und eine Write(data []byte) (int, error)-Methode implementieren, die Daten an den Körper anhängt. Fügen Sie eine Body() string-Methode hinzu, um die angesammelte Antwort abzurufen.

    Erstellen Sie ein MockRequest-Struct mit den String-Feldern Path und Method, um eine HTTP-Anfrage zu simulieren.

    Erstellen Sie nun zwei Handler-Structs, die das http.Handler-Interface-Muster implementieren (mit einer ServeHTTP-Methode, die einen *MockResponseWriter und einen *MockRequest entgegennimmt):

    • WelcomeHandler mit einem Message-Feld - schreibt die Nachricht gefolgt vom Pfad der Anfrage
    • MethodHandler - schreibt verschiedene Antworten basierend auf der Anfragemethode: "Fetching data" für GET, "Creating resource" für POST und "Method not supported" für alles andere
  • main.go: Verarbeiten Sie Anfragen über Ihre Handler.

    Lesen Sie einen Handler-Typ (welcome oder method) ein und lesen Sie dann die Anfragedetails. Für den Welcome-Handler lesen Sie zusätzlich die Willkommensnachricht ein.

    Erstellen Sie den entsprechenden Handler, bauen Sie einen Mock-Request und rufen Sie ServeHTTP auf, um ihn zu verarbeiten. Geben Sie den Antwortkörper aus.

Die folgenden Eingaben werden bereitgestellt:

  • Zeile 1: Handler-Typ (welcome oder method)
  • Zeile 2: Anfragepfad
  • Zeile 3: Anfragemethode
  • Zeile 4 (nur für welcome): Willkommensnachricht

Zum Beispiel, gegeben:

welcome
/home
GET
Hello from

Ihre Ausgabe sollte sein:

Hello from /home

Und gegeben:

method
/api/users
POST

Ihre Ausgabe sollte sein:

Creating resource

Und gegeben:

method
/api/data
GET

Ihre Ausgabe sollte sein:

Fetching data

Und gegeben:

method
/api/items
DELETE

Ihre Ausgabe sollte sein:

Method not supported

Diese Herausforderung demonstriert das Kernkonzept des http.Handler-Interfaces – jeder Typ mit einer ServeHTTP-Methode kann Anfragen verarbeiten. In realen Anwendungen stammen http.ResponseWriter und *http.Request aus der Standardbibliothek von Go, aber das Muster der Implementierung von Handlern bleibt genau gleich.

Spickzettel

Die Schnittstelle http.Handler ist die Grundlage der Webserver-Architektur von Go:

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

Jeder Typ mit einer ServeHTTP-Methode kann HTTP-Anfragen verarbeiten:

type GreetHandler struct {
    Greeting string
}

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

Registrieren Sie einen Handler beim Server:

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

Verwenden Sie für einfachere Fälle http.HandlerFunc, um eine Funktion in einen Handler zu konvertieren:

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

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

Handler können andere Handler umschließen, was Middleware-Muster für Logging, Authentifizierung oder andere querschnittliche Belange ermöglicht.

Probier es selbst

package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// Handler-Typ lesen
	scanner.Scan()
	handlerType := scanner.Text()
	
	// Anfragepfad lesen
	scanner.Scan()
	path := scanner.Text()
	
	// Anfragemethode lesen
	scanner.Scan()
	method := scanner.Text()
	
	// Mock-Anfrage erstellen
	request := &MockRequest{
		Path:   path,
		Method: method,
	}
	
	// Mock-Response-Writer erstellen
	response := &MockResponseWriter{}
	
	// TODO: Basierend auf handlerType den entsprechenden Handler erstellen
	// Wenn handlerType "welcome" ist, die Willkommensnachricht lesen und WelcomeHandler erstellen
	// Wenn handlerType "method" ist, MethodHandler erstellen
	// ServeHTTP auf dem Handler mit response und request aufrufen
	
	if handlerType == "welcome" {
		scanner.Scan()
		message := scanner.Text()
		// TODO: WelcomeHandler mit der Nachricht erstellen und ServeHTTP aufrufen
		_ = message // Diese Zeile bei der Implementierung entfernen
	} else if handlerType == "method" {
		// TODO: MethodHandler erstellen und ServeHTTP aufrufen
	}
	
	// Den Response-Body ausgeben
	fmt.Println(response.Body())
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung