Client HTTP en Go : faire des requêtes correctement de A à Z

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : Pourquoi il est important de savoir travailler avec HTTP en Go

\n

Go (Golang) est un langage conçu pour le travail en réseau. Sa bibliothèque standard net/http fournit des outils puissants et flexibles pour créer à la fois des serveurs et des clients. Cependant, de nombreux développeurs, surtout ceux venant de langages de script, commettent des erreurs typiques : ils oublient de fermer le corps de la réponse, ne définissent pas de timeouts ou gèrent incorrectement les erreurs.

\n

Dans cet article, nous allons détailler la création d'un client HTTP en Go « de A à Z ». Vous apprendrez à envoyer correctement des requêtes GET et POST, à gérer les en-têtes, à configurer les timeouts et à traiter les erreurs. Tous les exemples de code sont prêts à l'emploi.

\n\n

1. Bases : création du client et première requête GET

\n

En Go, le client HTTP est une structure http.Client. Vous pouvez utiliser le client global http.DefaultClient ou créer le vôtre avec des paramètres personnalisés. Commençons par une simple requête GET.

\n
package main\n\nimport (\n    "fmt"\n    "io"\n    "net/http"\n    "os"\n)\n\nfunc main() {\n    // Utilisation du client intégré\n    resp, err := http.Get("https://api.example.com/data")\n    if err != nil {\n        fmt.Printf("Erreur de requête : %v\\n", err)\n        os.Exit(1)\n    }\n    defer resp.Body.Close() // IMPORTANT : toujours fermer le corps de la réponse !\n\n    // Lecture du corps de la réponse\n    body, err := io.ReadAll(resp.Body)\n    if err != nil {\n        fmt.Printf("Erreur de lecture de la réponse : %v\\n", err)\n        os.Exit(1)\n    }\n\n    fmt.Printf("Statut : %s\\n", resp.Status)\n    fmt.Printf("Corps : %s\\n", string(body))\n}
\n

Points clés :

\n
    \n
  • Fermez toujours resp.Body avec defer. Sinon, une fuite de ressources se produit (les connexions ne retournent pas dans le pool).
  • \n
  • Vérifiez le statut de la réponse (resp.StatusCode). Le code 200 n'est pas le seul succès (il y a 201, 204, etc.).
  • \n
  • io.ReadAll lit tout le corps en mémoire. Pour les grandes réponses, utilisez io.Copy ou un traitement par flux.
  • \n
\n\n

2. Client avancé : timeouts, en-têtes et paramètres personnalisés

\n

Le client global n'a pas de timeouts par défaut — cela peut entraîner le blocage du programme. Créez toujours votre propre client avec des paramètres.

\n

2.1. Création d'un client avec timeout

\n
client := &http.Client{\n    Timeout: 10 * time.Second, // Timeout global pour toute la requête\n}\n\nresp, err := client.Get("https://api.example.com/data")
\n

Vous pouvez également configurer des timeouts à différents niveaux via Transport :

\n
transport := &http.Transport{\n    DialContext: (&net.Dialer{\n        Timeout:   5 * time.Second, // Timeout de connexion\n        KeepAlive: 30 * time.Second,\n    }).DialContext,\n    TLSHandshakeTimeout:   5 * time.Second,\n    ResponseHeaderTimeout: 5 * time.Second,\n}\n\nclient := &http.Client{\n    Transport: transport,\n    Timeout:   15 * time.Second,\n}
\n\n

2.2. Ajout d'en-têtes et de paramètres

\n

Pour les requêtes complexes, utilisez http.NewRequest :

\n
req, err := http.NewRequest("GET", "https://api.example.com/search", nil)\nif err != nil {\n    log.Fatal(err)\n}\n\n// Ajout d'en-têtes\nreq.Header.Set("Authorization", "Bearer your-token")\nreq.Header.Set("Accept", "application/json")\n\n// Ajout de paramètres de requête\nq := req.URL.Query()\nq.Add("query", "golang")\nq.Add("page", "1")\nreq.URL.RawQuery = q.Encode()\n\nresp, err := client.Do(req)
\n\n

3. Travail avec POST et autres méthodes (JSON, formulaires)

\n

Les requêtes POST nécessitent l'envoi d'un corps. Examinons deux formats populaires : JSON et formulaire URL-encodé.

\n

3.1. POST avec JSON

\n
type RequestData struct {\n    Name  string `json:"name"`\n    Email string `json:"email"`\n}\n\ndata := RequestData{\n    Name:  "Ivan",\n    Email: "ivan@example.com",\n}\n\njsonData, err := json.Marshal(da                

Blogs

Book Recommendations