Comment faire des requêtes HTTP en Go

De Get Docs
Aller à :navigation, rechercher

L'auteur a sélectionné le Diversity in Tech Fund pour recevoir un don dans le cadre du programme Write for DOnations.

Introduction

Lorsqu'un programme a besoin de communiquer avec un autre programme, de nombreux développeurs utilisent HTTP. L'une des forces de Go est l'étendue de sa bibliothèque standard, et HTTP ne fait pas exception. Le package Go net/http prend non seulement en charge la création de serveurs HTTP, mais il peut également effectuer des requêtes HTTP en tant que client.

Dans ce didacticiel, vous allez créer un programme qui envoie plusieurs types de requêtes HTTP à un serveur HTTP. Tout d'abord, vous allez faire une requête GET en utilisant le client Go HTTP par défaut. Ensuite, vous allez enrichir votre programme pour faire une requête POST avec un corps. Enfin, vous personnaliserez votre requête POST pour inclure un en-tête HTTP et ajouter un délai d'attente qui se déclenchera si votre requête prend trop de temps.

Conditions préalables

Pour suivre ce tutoriel, vous aurez besoin de :

Faire une requête GET

Le package Go net/http a plusieurs façons de l'utiliser en tant que client. Vous pouvez utiliser un client HTTP global commun avec des fonctions telles que http.Get pour effectuer rapidement une requête HTTP GET avec uniquement une URL et un corps, ou vous pouvez créer un http.Request pour commencer à personnaliser certains aspects de la demande individuelle. Dans cette section, vous allez créer un programme initial utilisant http.Get pour faire une requête HTTP, puis vous le mettrez à jour pour utiliser un http.Request avec le client HTTP par défaut.

Utiliser http.Get pour faire une demande

Dans la première itération de votre programme, vous utiliserez la fonction http.Get pour faire une demande au serveur HTTP que vous exécutez dans votre programme. La fonction http.Get est utile car vous n'avez pas besoin de configuration supplémentaire dans votre programme pour faire une requête. Si vous avez besoin de faire une seule demande rapide, http.Get peut être la meilleure option.

Pour commencer à créer votre programme, vous aurez besoin d'un répertoire dans lequel conserver le répertoire du programme. Dans ce didacticiel, vous utiliserez un répertoire nommé projects.

Commencez par créer le répertoire projects et accédez-y :

mkdir projects
cd projects

Ensuite, créez le répertoire de votre projet et accédez-y. Dans ce cas, utilisez le répertoire httpclient :

mkdir httpclient
cd httpclient

Dans le répertoire httpclient, utilisez nano, ou votre éditeur préféré, pour ouvrir le fichier main.go :

nano main.go

Dans le fichier main.go, commencez par ajouter ces lignes :

main.go

package main

import (
    "errors"
    "fmt"
    "net/http"
    "os"
    "time"
)

const serverPort = 3333

Vous ajoutez le nom package main afin que votre programme soit compilé en tant que programme que vous pouvez exécuter, puis incluez une instruction import avec les différents packages que vous utiliserez dans ce programme. Après cela, vous créez un const appelé serverPort avec la valeur 3333, que vous utiliserez comme port sur lequel votre serveur HTTP écoute et le port que votre client HTTP se connecter à.

Ensuite, créez une fonction main dans le fichier main.go et configurez une goroutine pour démarrer un serveur HTTP :

main.go

...
func main() {
    go func() {
        mux := http.NewServeMux()
        mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            fmt.Printf("server: %s /\n", r.Method)
        })
        server := http.Server{
            Addr:    fmt.Sprintf(":%d", serverPort),
            Handler: mux,
        }
        if err := server.ListenAndServe(); err != nil {
            if !errors.Is(err, http.ErrServerClosed) {
                fmt.Printf("error running http server: %s\n", err)
            }
        }
    }()

    time.Sleep(100 * time.Millisecond)

Votre serveur HTTP est configuré pour utiliser fmt.Printf pour imprimer des informations sur les demandes entrantes chaque fois que le chemin racine / est demandé. Il est également configuré pour écouter sur serverPort. Enfin, une fois que vous avez démarré la goroutine du serveur, votre programme utilise time.Sleep pendant une courte période. Ce temps de veille donne au serveur HTTP le temps dont il a besoin pour démarrer et commencer à fournir des réponses à la requête que vous ferez ensuite.

Maintenant, également dans la fonction main, configurez l'URL de requête en utilisant fmt.Sprintf pour combiner le nom d'hôte http://localhost avec la valeur serverPort sur laquelle le serveur écoute. Ensuite, utilisez http.Get pour envoyer une requête à cette URL, comme indiqué ci-dessous :

main.go

...
    requestURL := fmt.Sprintf("http://localhost:%d", serverPort)
    res, err := http.Get(requestURL)
    if err != nil {
        fmt.Printf("error making http request: %s\n", err)
        os.Exit(1)
    }

    fmt.Printf("client: got response!\n")
    fmt.Printf("client: status code: %d\n", res.StatusCode)
}

Lorsque la fonction http.Get est appelée, Go effectuera une requête HTTP en utilisant le client HTTP par défaut vers l'URL fournie, puis renverra soit une http.Response soit une valeur error si la demande échoue. Si la demande échoue, il imprimera l'erreur puis quittera votre programme en utilisant os.Exit avec un code d'erreur de 1. Si la requête aboutit, votre programme imprimera qu'il a reçu une réponse et le code d'état HTTP qu'il a reçu.

Enregistrez et fermez le fichier lorsque vous avez terminé.

Pour exécuter votre programme, utilisez la commande go run et fournissez-lui le fichier main.go :

go run main.go

Vous verrez la sortie suivante :

Outputserver: GET /
client: got response!
client: status code: 200

Sur la première ligne de sortie, le serveur imprime qu'il a reçu une requête GET de votre client pour le chemin /. Ensuite, les deux lignes suivantes indiquent que le client a reçu une réponse du serveur et que le code d'état de la réponse était 200.

La fonction http.Get est utile pour les requêtes HTTP rapides comme celle que vous avez faite dans cette section. Cependant, http.Request offre une gamme plus large d'options pour personnaliser votre demande.

Utiliser http.Request pour faire une demande

Contrairement à http.Get , la fonction http.Request vous offre un meilleur contrôle sur la requête, autre que la méthode HTTP et l'URL demandées. Vous n'utiliserez pas encore de fonctionnalités supplémentaires, mais en utilisant un http.Request maintenant, vous pourrez ajouter ces personnalisations plus tard dans ce didacticiel.

Dans votre code, la première mise à jour consiste à modifier le gestionnaire de serveur HTTP pour renvoyer une fausse réponse de données JSON à l'aide de fmt.Fprintf. S'il s'agissait d'un serveur HTTP complet, ces données seraient générées à l'aide du package encoding/json de Go. Si vous souhaitez en savoir plus sur l'utilisation de JSON dans Go, notre tutoriel Comment utiliser JSON dans Go est disponible. De plus, vous devrez également inclure io/ioutil en tant qu'importation pour une utilisation ultérieure dans cette mise à jour.

Maintenant, ouvrez à nouveau votre fichier main.go et mettez à jour votre programme pour commencer à utiliser un http.Request comme indiqué ci-dessous :

main.go

package main

import (
    ...
    "io/ioutil"
    ...
)

...

func main() {
    ...
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Printf("server: %s /\n", r.Method)
        fmt.Fprintf(w, `{"message": "hello!"}`)
    })
    ...

Maintenant, mettez à jour votre code de requête HTTP afin qu'au lieu d'utiliser http.Get pour faire une requête au serveur, vous utilisiez http.NewRequest et la méthode Do de http.DefaultClient :

main.go

...
    requestURL := fmt.Sprintf("http://localhost:%d", serverPort)
    req, err := http.NewRequest(http.MethodGet, requestURL, nil)
    if err != nil {
        fmt.Printf("client: could not create request: %s\n", err)
        os.Exit(1)
    }

    res, err := http.DefaultClient.Do(req)
    if err != nil {
        fmt.Printf("client: error making http request: %s\n", err)
        os.Exit(1)
    }

    fmt.Printf("client: got response!\n")
    fmt.Printf("client: status code: %d\n", res.StatusCode)

    resBody, err := ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.Printf("client: could not read response body: %s\n", err)
        os.Exit(1)
    }
    fmt.Printf("client: response body: %s\n", resBody)
}

Dans cette mise à jour, vous utilisez la fonction http.NewRequest pour générer une valeur http.Request ou gérez l'erreur si la valeur ne peut pas être créée. Contrairement à la fonction http.Get, cependant, la fonction http.NewRequest n'envoie pas immédiatement une requête HTTP au serveur. Comme il n'envoie pas la demande immédiatement, vous pouvez apporter les modifications que vous souhaitez à la demande avant qu'elle ne soit envoyée.

Une fois le http.Request créé et configuré, vous utilisez la méthode Do de http.DefaultClient pour envoyer la requête au serveur. La valeur http.DefaultClient est le client HTTP par défaut de Go, le même que vous avez utilisé avec http.Get. Cette fois, cependant, vous l'utilisez directement pour lui dire d'envoyer votre http.Request. La méthode Do du client HTTP renvoie les mêmes valeurs que vous avez reçues de la fonction http.Get afin que vous puissiez gérer la réponse de la même manière.

Après avoir imprimé les résultats de la requête, vous utilisez la fonction ioutil.ReadAll pour lire les Body de la réponse HTTP. Le Body est une valeur io.ReadCloser, une combinaison de io.Reader et io.Closer, ce qui signifie que vous pouvez lire données en utilisant tout ce qui peut lire à partir d'une valeur io.Reader. La fonction ioutil.ReadAll est utile car elle lira à partir d'un io.Reader jusqu'à ce qu'elle atteigne la fin des données ou rencontre un error. Ensuite, il renverra les données sous la forme d'une valeur []byte que vous pouvez imprimer en utilisant fmt.Printf, ou la valeur error qu'il a rencontrée.

Pour exécuter votre programme mis à jour, enregistrez vos modifications et utilisez la commande go run :

go run main.go

Cette fois, votre sortie devrait ressembler beaucoup à la précédente, mais avec un ajout :

Outputserver: GET /
client: got response!
client: status code: 200
client: response body: {"message": "hello!"}

Dans la première ligne, vous voyez que le serveur reçoit toujours une requête GET vers le chemin /. Le client reçoit également une réponse 200 du serveur, mais il lit et imprime également le Body de la réponse du serveur. Dans un programme plus complexe, vous pouvez ensuite prendre la valeur {"message": "hello!"} que vous avez reçue en tant que corps du serveur et la traiter en tant que JSON à l'aide du package encoding/json.

Dans cette section, vous avez créé un programme avec un serveur HTTP auquel vous avez adressé des requêtes HTTP de différentes manières. Tout d'abord, vous avez utilisé la fonction http.Get pour envoyer une requête GET au serveur en utilisant uniquement l'URL du serveur. Ensuite, vous avez mis à jour votre programme pour utiliser http.NewRequest afin de créer une valeur http.Request. Une fois que cela a été créé, vous avez utilisé la méthode Do du client HTTP par défaut de Go, http.DefaultClient, pour faire la demande et imprimer le http.Response Body à la sortie .

Cependant, le protocole HTTP utilise plus que les requêtes GET pour communiquer entre les programmes. Une requête GET est utile lorsque vous souhaitez recevoir des informations de l'autre programme, mais une autre méthode HTTP, la méthode POST, peut être utilisée lorsque vous souhaitez envoyer des informations de votre programme au serveur .

Envoi d'une requête POST

Dans une API REST, une requête GET n'est utilisée que pour récupérer des informations du serveur, donc pour que votre programme participe pleinement à une API REST, votre programme doit également prendre en charge l'envoi de [X200X ] requêtes. Une requête POST est presque l'inverse d'une requête GET, où le client envoie des données au serveur dans le corps de la requête.

Dans cette section, vous allez mettre à jour votre programme pour envoyer votre demande en tant que demande POST au lieu d'une demande GET. Votre requête POST inclura un corps de requête et vous mettrez à jour votre serveur pour imprimer plus d'informations sur les requêtes que vous faites depuis le client.

Pour commencer à effectuer ces mises à jour, ouvrez votre fichier main.go et ajoutez quelques nouveaux packages que vous utiliserez à votre relevé import :

main.go

...

import (
    "bytes"
    "errors"
    "fmt"
    "io/ioutil"
    "net/http"
    "os"
    "strings"
    "time"
)

...

Ensuite, mettez à jour votre fonction de gestionnaire de serveur pour imprimer diverses informations sur la requête entrante, telles que les valeurs de chaîne de requête, les valeurs d'en-tête et le corps de la requête :

main.go

...
  mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
      fmt.Printf("server: %s /\n", r.Method)
      fmt.Printf("server: query id: %s\n", r.URL.Query().Get("id"))
      fmt.Printf("server: content-type: %s\n", r.Header.Get("content-type"))
      fmt.Printf("server: headers:\n")
      for headerName, headerValue := range r.Header {
          fmt.Printf("\t%s = %s\n", headerName, strings.Join(headerValue, ", "))
      }

      reqBody, err := ioutil.ReadAll(r.Body)
      if err != nil {
             fmt.Printf("server: could not read request body: %s\n", err)
      }
      fmt.Printf("server: request body: %s\n", reqBody)

      fmt.Fprintf(w, `{"message": "hello!"}`)
  })
...

Dans cette mise à jour du gestionnaire de requêtes HTTP du serveur, vous ajoutez quelques instructions fmt.Printf plus utiles pour afficher des informations sur la requête entrante. Vous utilisez r.URL.Query().Get pour obtenir une valeur de chaîne de requête nommée id, et r.Header.Get pour obtenir la valeur d'un en-tête appelé content-type. Vous utilisez également une boucle for avec r.Header pour imprimer le nom et la valeur de chaque en-tête HTTP reçu par le serveur. Ces informations peuvent être utiles pour résoudre les problèmes si votre client ou votre serveur n'agit pas comme prévu. Enfin, vous avez également utilisé la fonction ioutil.ReadAll pour lire le corps de la requête HTTP dans r.Body.

Après avoir mis à jour la fonction de gestionnaire de serveur, mettez à jour le code de requête de la fonction main afin qu'elle envoie une requête POST avec un corps de requête :

main.go

...
 time.Sleep(100 * time.Millisecond)
    
 jsonBody := []byte(`{"client_message": "hello, server!"}`)
 bodyReader := bytes.NewReader(jsonBody)

 requestURL := fmt.Sprintf("http://localhost:%d?id=1234", serverPort)
 req, err := http.NewRequest(http.MethodPost, requestURL, bodyReader)
...

Dans votre mise à jour de la demande de la fonction main, l'une des nouvelles valeurs que vous définissez est la valeur jsonBody. Dans cet exemple, la valeur est représentée par un []byte au lieu du standard string car si vous utilisez le package encoding/json pour encoder les données JSON, cela vous donnera un [X172X ] au lieu d'un string.

La valeur suivante, le bodyReader, est un bytes.Reader qui encapsule les données jsonBody. Un corps http.Request nécessite que la valeur soit un io.Reader, et la valeur []byte de jsonBody n'implémente pas io.Reader, donc vous ne serait pas en mesure de l'utiliser comme corps de requête seul. La valeur bytes.Reader existe pour fournir cette interface io.Reader. Vous pouvez donc utiliser la valeur jsonBody comme corps de requête.

La valeur requestURL est également mise à jour pour inclure une valeur de chaîne de requête id=1234, principalement pour montrer comment une valeur de chaîne de requête peut également être incluse dans l'URL de la demande avec d'autres composants d'URL standard.

Enfin, l'appel de fonction http.NewRequest est mis à jour pour utiliser une méthode POST avec http.MethodPost, et le corps de la requête est inclus en mettant à jour le dernier paramètre d'un nil corps à bodyReader, les données JSON io.Reader.

Une fois que vous avez enregistré vos modifications, vous pouvez utiliser go run pour exécuter votre programme :

go run main.go

La sortie sera plus longue qu'avant en raison de vos mises à jour du serveur pour afficher des informations supplémentaires :

Outputserver: POST /
server: query id: 1234
server: content-type: 
server: headers:
        Accept-Encoding = gzip
        User-Agent = Go-http-client/1.1
        Content-Length = 36
server: request body: {"client_message": "hello, server!"}
client: got response!
client: status code: 200
client: response body: {"message": "hello!"}

La première ligne du serveur indique que votre requête est désormais transmise sous la forme d'une requête POST au chemin /. La deuxième ligne affiche la valeur 1234 de la valeur de chaîne de requête id que vous avez ajoutée à l'URL de la demande. La troisième ligne affiche la valeur de l'en-tête Content-Type envoyé par le client, qui se trouve être vide dans cette requête.

La quatrième ligne peut être légèrement différente de la sortie que vous voyez ci-dessus. Dans Go, l'ordre d'une valeur map n'est pas garanti lorsque vous les parcourez à l'aide de range, de sorte que vos en-têtes de r.Headers peuvent s'imprimer dans un ordre différent. Selon la version Go que vous utilisez, vous pouvez également voir une version User-Agent différente de celle ci-dessus.

Enfin, le dernier changement dans la sortie est que le serveur affiche le corps de la requête qu'il a reçu du client. Le serveur pourrait alors utiliser le package encoding/json pour analyser les données JSON envoyées par le client et formuler une réponse.

Dans cette section, vous avez mis à jour votre programme pour envoyer une requête HTTP POST au lieu d'une requête GET. Vous avez également mis à jour votre programme pour envoyer un corps de requête avec les données []byte lues par un bytes.Reader. Enfin, vous avez mis à jour la fonction de gestionnaire de serveur pour imprimer plus d'informations sur la requête effectuée par votre client HTTP.

Généralement, dans une requête HTTP, le client ou le serveur indique à l'autre le type de contenu qu'il envoie dans le corps. Comme vous l'avez vu dans la dernière sortie, cependant, votre requête HTTP n'incluait pas d'en-tête Content-Type pour indiquer au serveur comment interpréter les données du corps. Dans la section suivante, vous effectuerez quelques mises à jour pour personnaliser votre requête HTTP, notamment en définissant un en-tête Content-Type pour informer le serveur du type de données que vous envoyez.

Personnaliser une requête HTTP

Au fil du temps, les requêtes et les réponses HTTP ont été utilisées pour envoyer une plus grande variété de données entre les clients et les serveurs. À un moment donné, les clients HTTP pourraient supposer que les données qu'ils reçoivent d'un serveur HTTP sont HTML et ont de bonnes chances d'être correctes. Maintenant, cependant, il peut s'agir de HTML, JSON, de musique, de vidéo ou de tout autre type de données. Pour fournir plus d'informations sur les données envoyées via HTTP, le protocole inclut des en-têtes HTTP, et l'un de ces en-têtes importants est l'en-tête Content-Type. Cet en-tête indique au serveur (ou au client, selon la direction des données) comment interpréter les données qu'il reçoit.

Dans cette section, vous allez mettre à jour votre programme pour définir l'en-tête Content-Type sur votre requête HTTP afin que le serveur sache qu'il reçoit des données JSON. Vous mettrez également à jour votre programme pour utiliser un client HTTP autre que celui par défaut de Go http.DefaultClient afin de pouvoir personnaliser la manière dont la requête est envoyée.

Pour effectuer ces mises à jour, ouvrez à nouveau votre fichier main.go et mettez à jour votre fonction main comme suit :

main.go

...

  req, err := http.NewRequest(http.MethodPost, requestURL, bodyReader)
  if err != nil {
         fmt.Printf("client: could not create request: %s\n", err)
         os.Exit(1)
  }
  req.Header.Set("Content-Type", "application/json")

  client := http.Client{
     Timeout: 30 * time.Second,
  }

  res, err := client.Do(req)
  if err != nil {
      fmt.Printf("client: error making http request: %s\n", err)
      os.Exit(1)
  }

...

Dans cette mise à jour, vous accédez aux en-têtes http.Request à l'aide de req.Header, puis définissez la valeur de l'en-tête Content-Type sur la demande sur application/json. Le type de média application/json est défini dans la liste des types de média [1] comme type de média pour JSON. Ainsi, lorsque le serveur reçoit votre requête, il sait interpréter le corps comme JSON et non, par exemple, XML.

La prochaine mise à jour consiste à créer votre propre instance http.Client dans la variable client. Dans ce client, vous définissez la valeur Timeout sur 30 secondes. Ceci est important car il indique que toute demande faite avec le client abandonnera et cessera d'essayer de recevoir une réponse après 30 secondes. La valeur par défaut de Go http.DefaultClient ne spécifie pas de délai d'expiration, donc si vous faites une demande à l'aide de ce client, il attendra jusqu'à ce qu'il reçoive une réponse, soit déconnecté par le serveur ou que votre programme se termine. Si vous avez de nombreuses demandes qui traînent comme celle-ci en attente d'une réponse, vous utilisez peut-être un grand nombre de ressources sur votre ordinateur. La définition d'une valeur Timeout limite la durée d'attente d'une demande au moment que vous définissez.

Enfin, vous avez mis à jour votre requête pour utiliser la méthode Do de votre variable client. Vous n'avez pas besoin d'apporter d'autres modifications ici car vous avez appelé Do sur une valeur http.Client tout le temps. Le client HTTP par défaut de Go, http.DefaultClient, est juste un http.Client créé par défaut. Ainsi, lorsque vous avez appelé http.Get, la fonction appelait la méthode Do pour vous, et lorsque vous avez mis à jour votre requête pour utiliser http.DefaultClient, vous utilisiez ce [ X162X] directement. La seule différence maintenant est que vous avez créé la valeur http.Client que vous utilisez cette fois.

Maintenant, enregistrez votre fichier et exécutez votre programme en utilisant go run :

go run main.go

Votre sortie doit être très similaire à la sortie précédente, mais avec plus d'informations sur le type de contenu :

Outputserver: POST /
server: query id: 1234
server: content-type: application/json
server: headers:
        Accept-Encoding = gzip
        User-Agent = Go-http-client/1.1
        Content-Length = 36
        Content-Type = application/json
server: request body: {"client_message": "hello, server!"}
client: got response!
client: status code: 200
client: response body: {"message": "hello!"}

Vous verrez qu'il y a une valeur du serveur pour content-type, et il y a un en-tête Content-Type envoyé par le client. C'est ainsi que vous pourriez avoir le même chemin de requête HTTP servant à la fois une API JSON et une API XML. En spécifiant le type de contenu de la requête, le serveur et le client peuvent interpréter les données différemment.

Cet exemple ne déclenche cependant pas le délai d'expiration du client que vous avez configuré. Pour voir ce qui se passe lorsqu'une requête prend trop de temps et que le délai d'attente est déclenché, ouvrez votre fichier main.go et ajoutez un appel de fonction time.Sleep à votre fonction de gestionnaire de serveur HTTP. Ensuite, faites durer le time.Sleep plus longtemps que le délai d'attente que vous avez spécifié. Dans ce cas, vous le réglerez pendant 35 secondes :

main.go

...

func main() {
    go func() {
        mux := http.NewServeMux()
        mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            ... 
            fmt.Fprintf(w, `{"message": "hello!"}`)
            time.Sleep(35 * time.Second)
        })
        ...
    }()
    ...
}

Maintenant, enregistrez vos modifications et exécutez votre programme en utilisant go run :

go run main.go

Lorsque vous l'exécuterez cette fois, il faudra plus de temps pour quitter qu'auparavant car il ne se fermera qu'après la fin de la requête HTTP. Puisque vous avez ajouté le time.Sleep(35 * time.Second), la requête HTTP ne sera pas terminée tant que le délai de 30 secondes n'aura pas été atteint :

Outputserver: POST /
server: query id: 1234
server: content-type: application/json
server: headers:
        Content-Type = application/json
        Accept-Encoding = gzip
        User-Agent = Go-http-client/1.1
        Content-Length = 36
server: request body: {"client_message": "hello, server!"}
client: error making http request: Post "http://localhost:3333?id=1234": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
exit status 1

Dans cette sortie de programme, vous voyez que le serveur a reçu la demande et l'a traitée, mais lorsqu'il a atteint la fin de la fonction de gestionnaire HTTP où se trouve votre appel de fonction time.Sleep, il a commencé à dormir pendant 35 secondes. Dans le même temps, le délai d'expiration de votre requête HTTP est décompté et atteint la limite de 30 secondes avant la fin de la requête HTTP. Cela entraîne l'échec de l'appel de la méthode client.Do avec une erreur context deadline exceeded car le délai de 30 secondes de la demande est dépassé. Ensuite, votre programme se termine avec un code d'état d'échec de 1 en utilisant os.Exit(1).

Dans cette section, vous avez mis à jour votre programme pour personnaliser une requête HTTP en y ajoutant un en-tête Content-Type. Vous avez également mis à jour votre programme pour créer un nouveau http.Client avec un délai d'attente de 30 secondes, puis avez utilisé ce client pour effectuer une requête HTTP. Vous avez également testé le délai d'attente de 30 secondes en ajoutant un time.Sleep à votre gestionnaire de requêtes HTTP. Enfin, vous avez également vu pourquoi il est important d'utiliser vos propres valeurs http.Client avec des délais d'attente définis si vous souhaitez éviter que de nombreuses requêtes ne restent inactives.

Conclusion

Dans ce didacticiel, vous avez créé un nouveau programme avec un serveur HTTP et utilisé le package net/http de Go pour envoyer des requêtes HTTP à ce serveur. Tout d'abord, vous avez utilisé la fonction http.Get pour envoyer une requête GET au serveur avec le client HTTP par défaut de Go. Ensuite, vous avez utilisé http.NewRequest avec la méthode Do de http.DefaultClient pour faire une requête GET. Ensuite, vous avez mis à jour votre requête pour en faire une requête POST avec un corps utilisant bytes.NewReader. Enfin, vous avez utilisé la méthode Set sur un champ Header d'un http.Request pour définir l'en-tête Content-Type d'une requête et définir un délai d'attente de 30 secondes sur un la durée de la requête en créant votre propre client HTTP au lieu d'utiliser le client par défaut de Go.

Le package net/http inclut bien plus que les fonctionnalités que vous avez utilisées dans ce didacticiel. Il inclut également une fonction http.Post qui peut être utilisée pour faire une requête POST, similaire à la fonction http.Get. Le package prend également en charge l'enregistrement et la récupération des cookies, entre autres fonctionnalités.

Ce tutoriel fait également partie de la série DigitalOcean Comment coder dans Go. La série couvre un certain nombre de sujets Go, de l'installation de Go pour la première fois à l'utilisation du langage lui-même.