Requête POST avec JSON en Go : du débutant à la production

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

Envoyer du JSON dans une requête POST en Go : du "comment ça marche" au "fait et oublié"



Avez-vous déjà passé du temps sur Stack Overflow à essayer de comprendre pourquoi votre requête POST avec JSON en Go n'est pas acceptée par le serveur ? Ça vous dit quelque chose : tout semble correct, mais en réponse, vous obtenez une erreur 400 Bad Request ou un corps vide. Il s'avère qu'il existe plusieurs façons d'envoyer du JSON en Go, et choisir la bonne n'est pas seulement une question de goût, mais une question de stabilité pour votre microservice.



Dans cet article, nous ne nous contenterons pas de montrer du code. Nous analyserons trois approches : de la plus naïve (qui fonctionne mais est dangereuse) à une solution de production avec une gestion correcte des erreurs et des contextes. Si vous codez en Go pour des API, des bots ou des intégrations, cette lecture est indispensable.



Pourquoi ce sujet est-il si populaire ?

Go est un langage pour les services réseau. Tôt ou tard, tout développeur est confronté à la tâche : "envoyer du JSON dans le corps d'une requête POST". Cela semble simple, mais il y a des nuances :

  • Il faut sérialiser correctement la structure en JSON (marshaling).
  • Il est important de ne pas oublier l'en-tête Content-Type: application/json.
  • Il faut fermer correctement le corps de la réponse.
  • On souhaite éviter les fuites de mémoire et les paniques.

Analysons chaque approche avec des exemples concrets.



Approche 1 : "À la va-vite" — bytes.NewBuffer + json.Marshal

C'est la méthode la plus simple. On prend une structure, on la marshale en octets, on la met dans un buffer et on l'envoie. De nombreux développeurs Go débutants écrivent exactement comme ça.



package main

import ( "bytes" "encoding/json" "fmt" "net/http")

type User struct { Name string `json:"name"` Email string `json:"email"`}

func main() { user := User{Name: "Иван Петров", Email: "ivan@example.com"} // Étape 1 : marshaling de la structure en JSON jsonData, err := json.Marshal(user) if err != nil { fmt.Println("Erreur de marshaling :", err) return } // Étape 2 : création de la requête POST resp, err := http.Post( "https://api.example.com/users", "application/json", bytes.NewBuffer(jsonData), ) if err != nil { fmt.Println("Erreur de requête :", err) return } defer resp.Body.Close() fmt.Println("Statut :", resp.Status)}


Avantages et inconvénients de cette approche

  • Avantage : Minimum de code, compréhensible pour un débutant.
  • Inconvénient : Pas de flexibilité. Vous ne pouvez pas ajouter d'en-têtes personnalisés (authentification, trace-id). Pas de contrôle sur les timeouts. Si le serveur renvoie une erreur, vous ne la gérez pas.
  • Inconvénient : Problème potentiel : si json.Marshal renvoie une erreur, vous l'attrapez, mais dans le code réel, on oublie souvent de vérifier.

Cette méthode convient pour les prototypes et les tests. Pour la production, non.



Approche 2 : "La bonne" — http.NewRequest + json.NewEncoder

La communauté Go recommande d'utiliser http.NewRequest et json.NewEncoder. Pourquoi ? Parce que cela donne un contrôle total sur la requête et est plus efficace en mémoire.



package main

import ( "bytes" "encoding/json" "fmt" "net/http" "time")

type Order struct { ID int `json:"id"` Amount float64 `json:"amount"` Items []string `json:"items"`}

func sendOrder(order Order) error { // Création du buffer et de l'encodeur var buf bytes.Buffer enc := json.NewEncoder(&buf) // Encodage directement dans le buffer (sans []byte intermédiaire) if err := enc.Encode(order); err != nil { return fmt.Errorf("erreur d'encodage JSON : %w", err) } // Création de la requête req, err := http.NewRequest("POST", "https://api.example.com/orders", &buf) if err != nil { return fmt.Errorf("erreur de création de la requête : %w", err) } // Définition des en-têtes req.Header.Set("Content-Type", "application/json") req.Hea

Blogs

Book Recommendations