Einleitung
Go (Golang) ist eine moderne, kompilierte Sprache von Google, die sich ideal für die Erstellung hochlastiger Netzwerkdienste eignet. Das integrierte Paket net/http bietet einen leistungsstarken und flexiblen HTTP-Client, der die Interaktion mit REST APIs, Webservern und anderen HTTP-Ressourcen erleichtert. Trotz der scheinbaren Einfachheit machen Anfänger jedoch oft typische Fehler: Sie vergessen, den Antwortkörper zu schließen, behandeln Timeouts nicht oder ignorieren Fehler.
In diesem Artikel werden wir uns ansehen, wie man den HTTP-Client in Go richtig verwendet. Sie erfahren, wie Sie GET- und POST-Anfragen stellen, Header verwalten, Timeouts konfigurieren und Fehler behandeln. Alle Codebeispiele sind bereit für den Einsatz in Ihren Projekten.
1. Grundlagen: GET-Anfrage und Antwort lesen
Der einfachste Weg, eine GET-Anfrage durchzuführen, ist die Verwendung der Funktion http.Get(). Für Produktionscode wird jedoch empfohlen, eine eigene Instanz von http.Client zu erstellen – dies gibt Ihnen mehr Kontrolle über das Verhalten des Clients.
Einfache GET-Anfrage
package main
import ( "fmt" "io" "net/http" "os")
func main() { // Client erstellen (vorerst mit Standardeinstellungen) client := &http.Client{} // GET-Anfrage ausführen resp, err := client.Get("https://api.example.com/data") if err != nil { fmt.Fprintf(os.Stderr, "Anfragefehler: %v", err) os.Exit(1) } // WICHTIG: Antwortkörper schließen defer resp.Body.Close()
// Antwortkörper lesen body, err := io.ReadAll(resp.Body) if err != nil { fmt.Fprintf(os.Stderr, "Fehler beim Lesen des Körpers: %v", err) os.Exit(1) }
fmt.Printf("Status: %s", resp.Status) fmt.Printf("Körper: %s", body)}Wichtige Punkte:
defer resp.Body.Close()– schließen Sie den Antwortkörper unbedingt, sonst kommt es zu Ressourcenlecks (die Verbindung wird nicht in den Pool zurückgegeben).- Überprüfen Sie immer
err– das Netzwerk ist instabil und die Anfrage kann fehlschlagen. - Überprüfen Sie den HTTP-Status der Antwort (
resp.StatusCode), um Erfolg (2xx) von Serverfehlern (4xx, 5xx) zu unterscheiden.
2. POST-Anfrage mit Körper und Headern
Zum Senden von Daten an den Server (z. B. JSON) wird http.Post() oder die flexiblere Methode http.NewRequest() mit anschließendem Aufruf von client.Do() verwendet. Die zweite Methode ist vorzuziehen, da sie das Setzen von Headern und anderen Parametern ermöglicht.
POST mit JSON-Daten
package main
import ( "bytes" "encoding/json" "fmt" "net/http" "os")
type User struct { Name string `json:"name"` Email string `json:"email"`}
func main() { client := &http.Client{}
// Daten vorbereiten user := User{Name: "Ivan Petrov", Email: "ivan@example.com"} jsonData, err := json.Marshal(user) if err != nil { fmt.Fprintf(os.Stderr, "Fehler bei der JSON-Serialisierung: %v", err) os.Exit(1) }
// Anfrage erstellen req, err := http.NewRequest("POST", "https://api.example.com/users", bytes.NewBuffer(jsonData)) if err != nil { fmt.Fprintf(os.Stderr, "Fehler beim Erstellen der Anfrage: %v", err) os.Exit(1) }
// Header setzen req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer YOUR_TOKEN_HERE")
// Anfrage senden resp, err := client.Do(req) if err != nil { fmt.Fprintf(os.Stderr, "Anfragefehler: %v", err) os.Exit(1) } defer resp.Body.Close()
// Status prüfen if resp.StatusCode != http.StatusCreated { fmt.Fprintf(os.Stderr, "Server hat Fehler zurückgegeben: %s", resp.Status) os.Exit(1) }
fmt.Println("Benutzer erfolgreich erstellt!")}Wichtig