Menu
Coddy logo textTech

L'interface http.Handler

Fait partie de la section Programmation Orientée Objet du Journey GO de Coddy — leçon 77 sur 107.

L'interface http.Handler est le fondement de l'architecture du serveur web de Go. Elle définit la manière dont les requêtes HTTP sont traitées, et tout type l'implémentant peut répondre à des requêtes web.

L'interface est remarquablement simple :

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

Tout type possédant une méthode ServeHTTP peut gérer des requêtes HTTP. Voici un gestionnaire personnalisé :

type GreetHandler struct {
    Greeting string
}

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

Vous pouvez utiliser ce gestionnaire directement avec un serveur :

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

Pour des cas plus simples, Go fournit http.HandlerFunc, un type qui vous permet de convertir une fonction classique en un gestionnaire :

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

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

La puissance de cette interface devient évidente lorsque vous réalisez que les gestionnaires peuvent envelopper d'autres gestionnaires. Cela permet des modèles de middleware où vous ajoutez la journalisation, l'authentification ou d'autres préoccupations transversales sans modifier la logique du gestionnaire d'origine.

challenge icon

Défi

Facile

Construisons un système simple de gestionnaire HTTP qui simule la manière dont les requêtes web sont traitées ! Comme nous ne pouvons pas exécuter un véritable serveur HTTP dans cet environnement, vous allez créer des gestionnaires qui implémentent l'interface http.Handler et démontrer comment ils traitent les requêtes en travaillant avec des objets de requête/réponse fictifs (mock).

Vous organiserez votre code sur deux fichiers :

  • handlers.go : Définissez vos gestionnaires HTTP personnalisés.

    Créez une structure MockResponseWriter qui capture ce qui serait écrit dans une réponse HTTP. Elle doit stocker le corps de la réponse sous forme de chaîne de caractères et implémenter une méthode Write(data []byte) (int, error) qui ajoute les données au corps. Ajoutez une méthode Body() string pour récupérer la réponse accumulée.

    Créez une structure MockRequest avec des champs de type chaîne Path et Method pour simuler une requête HTTP.

    Créez maintenant deux structures de gestionnaire qui implémentent le modèle de l'interface http.Handler (avec une méthode ServeHTTP qui prend un *MockResponseWriter et un *MockRequest) :

    • WelcomeHandler avec un champ Message - écrit le message suivi du chemin de la requête
    • MethodHandler - écrit différentes réponses basées sur la méthode de la requête : "Fetching data" pour GET, "Creating resource" pour POST, et "Method not supported" pour tout le reste
  • main.go : Traitez les requêtes via vos gestionnaires.

    Lisez un type de gestionnaire (welcome ou method), puis lisez les détails de la requête. Pour le gestionnaire welcome, lisez également le message de bienvenue.

    Créez le gestionnaire approprié, construisez une requête fictive et appelez ServeHTTP pour la traiter. Affichez le corps de la réponse.

Les entrées suivantes seront fournies :

  • Ligne 1 : Type de gestionnaire (welcome ou method)
  • Ligne 2 : Chemin de la requête
  • Ligne 3 : Méthode de la requête
  • Ligne 4 (uniquement pour welcome) : Message de bienvenue

Par exemple, avec :

welcome
/home
GET
Hello from

Votre sortie devrait être :

Hello from /home

Et avec :

method
/api/users
POST

Votre sortie devrait être :

Creating resource

Et avec :

method
/api/data
GET

Votre sortie devrait être :

Fetching data

Et avec :

method
/api/items
DELETE

Votre sortie devrait être :

Method not supported

Ce défi démontre le concept central de l'interface http.Handler — n'importe quel type possédant une méthode ServeHTTP peut gérer des requêtes. Dans les applications réelles, le http.ResponseWriter et le *http.Request proviennent de la bibliothèque standard de Go, mais le modèle d'implémentation des gestionnaires reste exactement le même.

Aide-mémoire

L'interface http.Handler est le fondement de l'architecture du serveur web de Go :

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

Tout type possédant une méthode ServeHTTP peut gérer des requêtes HTTP :

type GreetHandler struct {
    Greeting string
}

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

Enregistrez un gestionnaire auprès du serveur :

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

Pour les cas plus simples, utilisez http.HandlerFunc pour convertir une fonction en un gestionnaire :

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

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

Les gestionnaires peuvent envelopper d'autres gestionnaires, permettant des modèles de middleware pour la journalisation, l'authentification ou d'autres préoccupations transversales.

Essayez vous-même

package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// Lire le type de gestionnaire
	scanner.Scan()
	handlerType := scanner.Text()
	
	// Lire le chemin de la requête
	scanner.Scan()
	path := scanner.Text()
	
	// Lire la méthode de la requête
	scanner.Scan()
	method := scanner.Text()
	
	// Créer une simulation de requête
	request := &MockRequest{
		Path:   path,
		Method: method,
	}
	
	// Créer une simulation de rédacteur de réponse
	response := &MockResponseWriter{}
	
	// TODO: En fonction de handlerType, créer le gestionnaire approprié
	// Si handlerType est "welcome", lire le message de bienvenue et créer WelcomeHandler
	// Si handlerType est "method", créer MethodHandler
	// Appeler ServeHTTP sur le gestionnaire avec response et request
	
	if handlerType == "welcome" {
		scanner.Scan()
		message := scanner.Text()
		// TODO: Créer WelcomeHandler avec le message et appeler ServeHTTP
		_ = message // Supprimer cette ligne lors de l'implémentation
	} else if handlerType == "method" {
		// TODO: Créer MethodHandler et appeler ServeHTTP
	}
	
	// Afficher le corps de la réponse
	fmt.Println(response.Body())
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet