【Introduction】This article introduces the Go language’s standard library net/http.
The built-in net/http package in Go is excellent, providing implementations for both HTTP clients and servers.
Introduction to net/http
The built-in net/http package in Go provides implementations for both HTTP clients and servers.
HTTP Protocol
The HyperText Transfer Protocol (HTTP) is the most widely used network transfer protocol on the Internet, and all WWW files must adhere to this standard. The initial design purpose of HTTP was to provide a method for publishing and receiving HTML pages.
HTTP Client
Basic HTTP/HTTPS Requests
The Get, Head, Post, and PostForm functions issue HTTP/HTTPS requests.
resp, err := http.Get("http://example.com/")...resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)...resp, err := http.PostForm("http://example.com/form", url.Values{"key": {"Value"}, "id": {"123"}})
After using the response, the program must close the response body.
resp, err := http.Get("http://example.com/")if err != nil { // handle error}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)// ...
👉Click to receive Go backend development resources
GET Request Example
Using the net/http package, write a simple client to send an HTTP request. The code is as follows:
package main
import ( "fmt" "io/ioutil" "net/http")
func main() { resp, err := http.Get("https://www.liwenzhou.com/") if err != nil { fmt.Printf("get failed, err:%v\n", err) return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Printf("read from resp.Body failed, err:%v\n", err) return } fmt.Print(string(body))}
Save the above code, compile it into an executable file, and execute it to print the content of the liwenzhou.com homepage in the terminal. Our browser is essentially a client that sends and receives HTTP protocol data. When we access a webpage through the browser, we are actually receiving HTTP data from the website’s server, and the browser renders the webpage according to HTML, CSS, and other rules.
GET Request with Parameters Example
Parameters for GET requests need to be handled using the Go language’s built-in net/url standard library.
func main() { apiUrl := "http://127.0.0.1:9090/get" // URL param data := url.Values{} data.Set("name", "mi") data.Set("age", "18") u, err := url.ParseRequestURI(apiUrl) if err != nil { fmt.Printf("parse url requestUrl failed, err:%v\n", err) } u.RawQuery = data.Encode() // URL encode fmt.Println(u.String()) resp, err := http.Get(u.String()) if err != nil { fmt.Printf("post failed, err:%v\n", err) return } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Printf("get resp failed, err:%v\n", err) return } fmt.Println(string(b))}
The corresponding server-side HandlerFunc is as follows:
func getHandler(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() data := r.URL.Query() fmt.Println(data.Get("name")) fmt.Println(data.Get("age")) answer := `{"status": "ok"}` w.Write([]byte(answer))}
POST Request Example
The above demonstrated an example of sending a GET request using the net/http package. The example code for sending a POST request is as follows:
package main
import ( "fmt" "io/ioutil" "net/http" "strings")
// net/http post demo
func main() { url := "http://127.0.0.1:9090/post" // form data //contentType := "application/x-www-form-urlencoded" //data := "name=mi&age=18" // json contentType := "application/json" data := `{"name":"mi","age":18}` resp, err := http.Post(url, contentType, strings.NewReader(data)) if err != nil { fmt.Printf("post failed, err:%v\n", err) return } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Printf("get resp failed, err:%v\n", err) return } fmt.Println(string(b))}
The corresponding server-side HandlerFunc is as follows:
func postHandler(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() // 1. When the request type is application/x-www-form-urlencoded, parse the form data r.ParseForm() fmt.Println(r.PostForm) // Print form data fmt.Println(r.PostForm.Get("name"), r.PostForm.Get("age")) // 2. When the request type is application/json, read data from r.Body b, err := ioutil.ReadAll(r.Body) if err != nil { fmt.Printf("read request.Body failed, err:%v\n", err) return } fmt.Println(string(b)) answer := `{"status": "ok"}` w.Write([]byte(answer))}
Custom Client
To manage HTTP client headers, redirect policies, and other settings, create a Client:
client := &http.Client{ CheckRedirect: redirectPolicyFunc,}resp, err := client.Get("http://example.com")// ...req, err := http.NewRequest("GET", "http://example.com", nil)// ...req.Header.Add("If-None-Match", `W/"wyzzy"`)resp, err := client.Do(req)// ...
Custom Transport
To manage proxies, TLS configurations, keep-alive, compression, and other settings, create a Transport:
tr := &http.Transport{ TLSClientConfig: &tls.Config{RootCAs: pool}, DisableCompression: true,}client := &http.Client{Transport: tr}resp, err := client.Get("https://example.com")
Both Client and Transport types can be safely used by multiple goroutines simultaneously. For efficiency, they should be established once and reused as much as possible.
Server
Default Server
ListenAndServe starts an HTTP server using the specified listening address and handler. The handler parameter is usually nil, which indicates using the package variable DefaultServeMux as the handler.
The Handle and HandleFunc functions can add handlers to DefaultServeMux.
http.Handle("/foo", fooHandler)http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))})log.Fatal(http.ListenAndServe(":8080", nil))
Default Server Example
Use the net/http package in Go to write a simple server that receives HTTP requests. The net/http package is a further encapsulation of the net package, specifically designed to handle HTTP protocol data. The specific code is as follows:
// http serverpackage main
import ( "fmt" "net/http")
func sayHello(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello Shanghai!")}
func main() { http.HandleFunc("/", sayHello) err := http.ListenAndServe(":9090", nil) if err != nil { fmt.Printf("http server failed, err:%v\n", err) return }}
Compile the above code and execute it, then open your browser and enter 127.0.0.1:9090 in the address bar to see the following page.
Custom Server
To manage server behavior, you can create a custom server:
s := &http.Server{ Addr: ":8080", Handler: myHandler, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, MaxHeaderBytes: 1 << 20,}log.Fatal(s.ListenAndServe())