Ce face net/http.NewRequest
Când http.Get și http.Post nu ajung (ai nevoie de PUT sau DELETE, de antete ca Authorization, de un context), construiești cererea cu http.NewRequest(metoda, url, corp), îi setezi antetele în req.Header și o trimiți cu client.Do(req). Pentru cereri fără corp, body este nil.
http.NewRequestWithContext(ctx, ...) leagă cererea de un context: dacă contextul este anulat sau expiră, cererea este întreruptă, inclusiv citirea corpului răspunsului. În cod nou, preferă această variantă; NewRequest folosește context.Background().
Funcția returnează eroare doar dacă metoda sau adresa sunt invalide; nicio cerere nu pleacă până la Do.
Parametri
| Parametru | Descriere |
|---|---|
ctx |
Contextul care poate anula cererea (doar la NewRequestWithContext). |
method |
Metoda: "GET", "POST", "PUT", "DELETE" sau constantele http.MethodGet etc. |
url |
Adresa completă. |
body |
Corpul cererii sau nil. |
Ce returnează
Cererea (*http.Request) și o eroare.
Exemple
Exemplul 1: PUT cu antet de autentificare
package main
import (
"fmt"
"io"
"net/http"
"net/http/httptest"
"strings"
)
func main() {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
corp, _ := io.ReadAll(r.Body)
fmt.Fprintf(w, "%s %s\nAuthorization: %s\nCorp: %s\n", r.Method, r.URL.Path, r.Header.Get("Authorization"), corp)
}))
defer srv.Close()
req, err := http.NewRequest(http.MethodPut, srv.URL+"/produse/17", strings.NewReader(`{"pret": 35}`))
if err != nil {
fmt.Println(err)
return
}
req.Header.Set("Authorization", "Bearer token-secret")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
raspuns, _ := io.ReadAll(resp.Body)
fmt.Print(string(raspuns))
_, err = http.NewRequest("GET", "://adresa gresita", nil)
fmt.Println("URL invalid:", err)
}
Rezultat
PUT /produse/17
Authorization: Bearer token-secret
Corp: {"pret": 35}
URL invalid: parse "://adresa gresita": missing protocol scheme
Exemplul 2: Cerere anulată de context
package main
import (
"context"
"errors"
"fmt"
"net/http"
"net/http/httptest"
"time"
)
func main() {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
select {
case <-time.After(time.Second):
case <-r.Context().Done():
}
}))
defer srv.Close()
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
defer cancel()
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, srv.URL, nil)
_, err := http.DefaultClient.Do(req)
fmt.Println("Eroare:", err != nil)
fmt.Println("Din cauza limitei de timp:", errors.Is(err, context.DeadlineExceeded))
}
Rezultat
Eroare: true
Din cauza limitei de timp: true
Greșeli frecvente
- Construiești cererea, dar uiți să o trimiți:
NewRequestdoar o pregătește;client.Do(req)o trimite. - Setezi antetul
Hostprinreq.Header.Set("Host", ...): este ignorat. Folosește câmpulreq.Host.
Comenzi înrudite
net/http.Client: Clientul HTTP configurabil (limită de timp, redirecționări, cookie-uri); Do trimite o cerere, Get o cerere GET.net/http.Request: Structura unei cereri HTTP: metoda, URL-ul, antetele, corpul și contextul (Context()) care se anulează când clientul pleacă.net/http.Header: Antetele unei cereri sau ale unui răspuns: Get citește, Set înlocuiește, Add adaugă încă o valoare, Del șterge.context.WithTimeout: Creează un context care se anulează singur după durata dată; limita de timp standard pentru cereri și interogări.