Contactez-nous

Exemple rapide : serveur web simple avec `net/http`

Découvrez comment créer un serveur HTTP basique en Go en quelques lignes avec `net/http`. Gérez les requêtes et envoyez des réponses simples.

Go et le Web : Introduction à `net/http`

L'une des forces de Go est sa capacité à construire des services réseau performants, et notamment des serveurs web, grâce à sa bibliothèque standard très complète. Le paquet `net/http` fournit toutes les briques nécessaires pour créer des clients et des serveurs HTTP robustes et efficaces.

Que vous souhaitiez construire une API RESTful, servir des pages web dynamiques ou statiques, ou simplement créer un petit service qui répond à des requêtes HTTP, `net/http` est le point de départ incontournable en Go.

Dans ce sous-chapitre, nous allons illustrer la simplicité avec laquelle vous pouvez mettre en place un serveur web fonctionnel qui répond à des requêtes sur une route spécifique. Cet exemple, bien que basique, démontre les concepts fondamentaux de la gestion des requêtes et des réponses HTTP en Go.

Les composants clés : Handler et Serveur

Pour créer un serveur web avec `net/http`, nous avons besoin de deux éléments principaux :

1. Un ou plusieurs Handlers (Gestionnaires) : Ce sont des fonctions (ou des objets implémentant l'interface `http.Handler`) responsables de traiter les requêtes HTTP entrantes pour un chemin d'URL spécifique et de générer une réponse HTTP.

2. Le Serveur HTTP lui-même : Il écoute sur un port réseau spécifique, accepte les connexions entrantes, lit les requêtes HTTP, et les achemine vers le handler approprié en fonction du chemin demandé.

Le paquet `net/http` fournit des fonctions simples pour définir ces composants et démarrer le serveur.

Etape 1 : Définir une fonction Handler

Un handler en Go est typiquement une fonction qui respecte une signature spécifique : `func(w http.ResponseWriter, r *http.Request)`.

  • `w http.ResponseWriter` : C'est une interface utilisée pour construire et envoyer la réponse HTTP au client (définir le statut, les en-têtes, écrire le corps de la réponse).
  • `r *http.Request` : C'est une structure contenant toutes les informations sur la requête HTTP reçue du client (méthode, URL, en-têtes, corps de la requête, etc.).

Créons une fonction handler simple qui répondra "Bonjour, visiteur !" à toute requête :

package main

import (
    "fmt"
    "net/http"
)

// Notre fonction handler pour la route "/"
func bonjourHandler(w http.ResponseWriter, r *http.Request) {
    // Ecrit la réponse dans le ResponseWriter
    // Fprintf fonctionne comme Sprintf mais écrit dans un io.Writer (ici w)
    fmt.Fprintf(w, "Bonjour, visiteur !") 
}

// (Le reste du code viendra ensuite)
Cette fonction `bonjourHandler` prend `w` et `r` comme arguments et utilise `fmt.Fprintf` pour écrire la chaîne de réponse directement dans le `ResponseWriter` `w`.

Etape 2 : Enregistrer le Handler et démarrer le serveur

Maintenant que nous avons notre fonction handler, nous devons dire au serveur HTTP de l'utiliser lorsqu'une requête arrive sur un chemin spécifique (par exemple, la racine `/`). Cela se fait avec `http.HandleFunc`.

Ensuite, nous devons démarrer le serveur pour qu'il écoute les connexions entrantes sur un port donné (par exemple, le port 8080). La fonction `http.ListenAndServe` fait exactement cela.

Voici le code complet du serveur :

package main

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

// Notre fonction handler pour la route "/"
func bonjourHandler(w http.ResponseWriter, r *http.Request) {
    // Log simple pour voir les requêtes arriver (optionnel)
    log.Printf("Requête reçue pour: %s", r.URL.Path)
    fmt.Fprintf(w, "Bonjour, visiteur !")
}

// Fonction handler pour une autre route "/salut"
func salutHandler(w http.ResponseWriter, r *http.Request) {
    log.Printf("Requête reçue pour: %s", r.URL.Path)
    fmt.Fprintf(w, "Salut tout le monde !")
}

func main() {
    // Enregistre bonjourHandler pour gérer les requêtes sur le chemin "/"
    http.HandleFunc("/", bonjourHandler) 

    // Enregistre salutHandler pour gérer les requêtes sur le chemin "/salut"
    http.HandleFunc("/salut", salutHandler)

    port := ":8080" // Port sur lequel écouter (le ':' est important)
    fmt.Printf("Serveur démarré sur http://localhost%s\n", port)

    // Démarre le serveur HTTP. 
    // ListenAndServe bloque l'exécution jusqu'à ce que le serveur soit arrêté
    // (ou qu'une erreur critique se produise).
    // S'il y a une erreur au démarrage (ex: port déjà utilisé), elle est retournée.
    err := http.ListenAndServe(port, nil) // Le 'nil' utilise le DefaultServeMux (où HandleFunc enregistre)
    if err != nil {
        log.Fatal("Erreur ListenAndServe: ", err)
    }
}

Exécution et Test

Pour exécuter ce serveur :

  1. Enregistrez le code ci-dessus dans un fichier (par exemple, `serveur.go`).
  2. Ouvrez votre terminal, naviguez jusqu'au répertoire du fichier.
  3. Exécutez la commande : `go run serveur.go`
  4. Vous devriez voir le message "Serveur démarré sur http://localhost:8080". Le programme restera bloqué à ce stade, car `ListenAndServe` écoute activement.
  5. Ouvrez votre navigateur web et allez à l'adresse `http://localhost:8080/`. Vous devriez voir la page afficher "Bonjour, visiteur !".
  6. Allez ensuite à l'adresse `http://localhost:8080/salut`. Vous devriez voir "Salut tout le monde !".
  7. Si vous allez à une autre adresse, comme `http://localhost:8080/autre`, le `bonjourHandler` (enregistré pour `/`) pourrait la capturer selon la configuration du multiplexeur par défaut, ou vous pourriez obtenir une erreur 404 si aucun handler ne correspond plus spécifiquement.
  8. Pour arrêter le serveur, retournez à votre terminal et appuyez sur `Ctrl+C`.

Dans le terminal où le serveur s'exécute, vous verrez également les messages de log pour chaque requête reçue.

Conclusion : La simplicité du web en Go

Cet exemple très simple démontre la facilité avec laquelle on peut créer un serveur HTTP fonctionnel en Go en utilisant uniquement la bibliothèque standard `net/http`.

Les étapes clés sont : définir des fonctions handlers (`func(http.ResponseWriter, *http.Request)`), les enregistrer pour des chemins spécifiques avec `http.HandleFunc`, et démarrer le serveur avec `http.ListenAndServe`.

Bien sûr, le développement web réel implique beaucoup plus de complexité (routage avancé, middlewares, gestion des templates, interaction avec des bases de données, etc.), pour lesquelles des frameworks web comme Gin, Echo ou Chi sont souvent utilisés. Cependant, `net/http` reste la fondation sur laquelle tout repose, et le comprendre est essentiel même lorsque vous utilisez un framework.