Comment faire des requêtes HTTP en Go
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 :
- Go version 1.16 ou supérieure installée. Pour le configurer, suivez le tutoriel Comment installer Go pour votre système d'exploitation.
- Expérience de la création d'un serveur HTTP dans Go, que vous trouverez dans le didacticiel, Comment créer un serveur HTTP dans Go.
- Familiarité avec les goroutines et les chaînes de lecture. Pour plus d'informations, consultez le didacticiel, Comment exécuter plusieurs fonctions simultanément dans Go.
- Il est recommandé de comprendre comment une requête HTTP est composée et envoyée.
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.