Ce face net/http.Response
Funcțiile client (Get, Post, Client.Do) returnează un *http.Response. StatusCode este numărul (200, 404), Status textul complet ("404 Not Found"), Header antetele, iar Body corpul, citit ca flux (io.ReadAll, json.NewDecoder, io.Copy într-un fișier).
Body nu este niciodată nil când err == nil și trebuie închis întotdeauna, chiar dacă nu îl citești. ContentLength este mărimea anunțată (-1 dacă nu se știe), iar Request este cererea care a produs răspunsul (după redirecționări, ultima).
Pe server, același tip apare în teste: httptest.ResponseRecorder.Result() returnează un *http.Response.
Ce returnează
Este o structură; câmpurile ei se citesc direct.
Exemple
Exemplul 1: Câmpurile unui răspuns
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
)
func main() {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("X-Total", "2")
fmt.Fprint(w, `[{"oras":"Iași","temp":14},{"oras":"Cluj","temp":11}]`)
}))
defer srv.Close()
resp, err := http.Get(srv.URL + "/meteo")
if err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
fmt.Println("Status: ", resp.Status)
fmt.Println("StatusCode: ", resp.StatusCode)
fmt.Println("Content-Type: ", resp.Header.Get("Content-Type"))
fmt.Println("X-Total: ", resp.Header.Get("X-Total"))
fmt.Println("ContentLength:", resp.ContentLength)
fmt.Println("Cererea: ", resp.Request.Method, resp.Request.URL.Path)
var vreme []struct {
Oras string `json:"oras"`
Temp int `json:"temp"`
}
if err := json.NewDecoder(resp.Body).Decode(&vreme); err != nil {
fmt.Println(err)
return
}
for _, v := range vreme {
fmt.Printf("%s: %d °C\n", v.Oras, v.Temp)
}
}
Rezultat
Status: 200 OK
StatusCode: 200
Content-Type: application/json
X-Total: 2
ContentLength: 54
Cererea: GET /meteo
Iași: 14 °C
Cluj: 11 °C
Exemplul 2: Clasificarea după codul de stare
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"strconv"
)
func main() {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
cod, _ := strconv.Atoi(r.URL.Query().Get("cod"))
w.WriteHeader(cod)
}))
defer srv.Close()
for _, cod := range []string{"200", "204", "404", "503"} {
resp, err := http.Get(srv.URL + "/?cod=" + cod)
if err != nil {
fmt.Println(err)
return
}
resp.Body.Close()
switch {
case resp.StatusCode >= 200 && resp.StatusCode < 300:
fmt.Println(resp.Status, "-> succes")
case resp.StatusCode >= 400 && resp.StatusCode < 500:
fmt.Println(resp.Status, "-> greșeala clientului")
default:
fmt.Println(resp.Status, "-> problemă la server, reîncearcă")
}
}
}
Rezultat
200 OK -> succes
204 No Content -> succes
404 Not Found -> greșeala clientului
503 Service Unavailable -> problemă la server, reîncearcă
Greșeli frecvente
- Compari
resp.Status == "200".Statuseste"200 OK"; comparăresp.StatusCode == http.StatusOK. - Nu închizi
Bodypentru răspunsurile de eroare pe care nu le citești: conexiunea nu este eliberată.
Comenzi înrudite
net/http.Get: Trimite o cerere GET (sau HEAD, doar antete) la adresa dată și returnează răspunsul; corpul trebuie închis.net/http.Client: Clientul HTTP configurabil (limită de timp, redirecționări, cookie-uri); Do trimite o cerere, Get o cerere GET.net/http.Header: Antetele unei cereri sau ale unui răspuns: Get citește, Set înlocuiește, Add adaugă încă o valoare, Del șterge.encoding/json.NewDecoder: Creează un Decoder care citește JSON dintr-un io.Reader (corpul unei cereri, un fișier); Decode citește o valoare.