Ce face net/http.HandleFunc
http.HandleFunc("/contact", f) spune: cererile pentru /contact sunt tratate de funcția f. http.Handle face același lucru, dar primește o valoare care implementează interfața http.Handler (are metoda ServeHTTP), de exemplu un http.FileServer.
Rutele ajung în http.DefaultServeMux, routerul global folosit de http.ListenAndServe(addr, nil). Modelele urmează regulile lui ServeMux: "/" prinde tot ce nu se potrivește altundeva, un model terminat în / prinde tot subarborele, iar din Go 1.22 poți scrie metoda și parametri: "GET /produse/{id}".
Routerul global este comod pentru programe mici, dar orice pachet importat îl poate modifica. În aplicații mai mari creează propriul router cu http.NewServeMux(); metodele lui au aceleași nume.
Parametri
| Parametru | Descriere |
|---|---|
pattern |
Modelul rutei: "/", "/despre", "/static/", "POST /comenzi". |
handler |
Funcția func(w http.ResponseWriter, r *http.Request) (la HandleFunc) sau un http.Handler (la Handle). |
Ce returnează
Nimic. Dacă modelul este invalid sau înregistrat de două ori, programul se oprește cu panică.
Exemple
Exemplul 1: Mai multe rute în routerul global
package main
import (
"fmt"
"io"
"net/http"
"net/http/httptest"
)
type Ora struct{ Oras string }
func (o Ora) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Ora în %s: 14:30\n", o.Oras)
}
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Pagina principală, ai cerut", r.URL.Path)
})
http.HandleFunc("/despre", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Magazinul Dexter, Iași")
})
http.Handle("/ora", Ora{Oras: "București"})
srv := httptest.NewServer(http.DefaultServeMux)
defer srv.Close()
for _, cale := range []string{"/", "/despre", "/ora", "/altceva"} {
resp, err := http.Get(srv.URL + cale)
if err != nil {
fmt.Println(err)
return
}
corp, _ := io.ReadAll(resp.Body)
resp.Body.Close()
fmt.Printf("%-9s -> %s", cale, corp)
}
}
Rezultat
/ -> Pagina principală, ai cerut /
/despre -> Magazinul Dexter, Iași
/ora -> Ora în București: 14:30
/altceva -> Pagina principală, ai cerut /altceva
Exemplul 2: Metodă și parametru în model (Go 1.22)
GET /salut/{nume} acceptă doar cereri GET; o cerere POST primește 405 Method Not Allowed.
package main
import (
"fmt"
"io"
"net/http"
"net/http/httptest"
"strings"
)
func main() {
http.HandleFunc("GET /salut/{nume}", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Salut, %s!\n", r.PathValue("nume"))
})
srv := httptest.NewServer(http.DefaultServeMux)
defer srv.Close()
resp, _ := http.Get(srv.URL + "/salut/Maria")
corp, _ := io.ReadAll(resp.Body)
resp.Body.Close()
fmt.Print(resp.StatusCode, " ", string(corp))
resp, _ = http.Post(srv.URL+"/salut/Maria", "text/plain", strings.NewReader(""))
resp.Body.Close()
fmt.Println(resp.Status)
}
Rezultat
200 Salut, Maria!
405 Method Not Allowed
Greșeli frecvente
- Apelezi funcția în loc să o dai ca valoare:
http.HandleFunc("/", acasa()). Scriehttp.HandleFunc("/", acasa), fără paranteze. - Înregistrezi același model de două ori (de exemplu în teste rulate de mai multe ori): programul se oprește cu panică. Folosește un
ServeMuxnou pentru fiecare test. - Te aștepți ca
"/"să prindă doar pagina principală. Prinde orice cale care nu are altă rută; pentru exact „/” folosește modelul"/{$}".
Comenzi înrudite
net/http.NewServeMux: Creează un router (ServeMux) propriu care alege handler-ul după metoda și calea cererii; HandleFunc și Handle adaugă rute.net/http.Handler: Interfața oricărui obiect care răspunde la cereri HTTP (metoda ServeHTTP); HandlerFunc transformă o funcție în Handler.net/http.ListenAndServe: Pornește un server web pe adresa dată (ex. „:8080”) și răspunde la cereri cu handler-ul dat; rulează până la oprire.net/http.Request.PathValue: Returnează valoarea unui parametru din calea rutei, de exemplu id din modelul „/produse/{id}”.