Skip to content

Gói http trong Go

Gói net/http trong thư viện chuẩn Go rất xuất sắc, cung cấp triển khai HTTP client và server hoàn chỉnh, chỉ với vài dòng code đã có thể xây dựng một HTTP server đơn giản.

Hầu hết các framework web trong Go đều là đóng gói và sửa đổi dựa trên gói http hiện có, vì vậy rất nên học và nắm vững gói http trước khi tìm hiểu các framework khác.

Ví dụ Get

Về kiến thức liên quan đến Http, ở đây không đề cập thêm, muốn tìm hiểu thêm có thể tra cứu trên mạng.

go
func main() {
  resp, err := http.Get("https://baidu.com")
  if err != nil {
    fmt.Println(err)
    return
  }
  defer resp.Body.Close()
  content, err := io.ReadAll(resp.Body)
  fmt.Println(string(content))
}

Chỉ cần gọi hàm trong gói Http là có thể gửi request đơn giản, sẽ trả về một con trỏ và lỗi, sau khi gọi phải đóng nó thủ công.

Ví dụ Post

go
func main() {
   person := Person{
      UserId:   "120",
      Username: "jack",
      Age:      18,
      Address:  "usa",
   }

   json, _ := json.Marshal(person)
   reader := bytes.NewReader(json)

   resp, err := http.Post("https://golang.org", "application/json;charset=utf-8", reader)
   if err != nil {
      fmt.Println(err)
   }
   defer resp.Body.Close()
}

Client

Thông thường, chúng ta không sử dụng trực tiếp các phương thức trên mà sẽ tự cấu hình một client để đáp ứng các yêu cầu chi tiết hơn. Sẽ cần sử dụng cấu trúc http.Client{}, có tổng cộng bốn mục cấu hình có thể cung cấp:

  • Transport: Cấu hình liên quan đến truyền tải dữ liệu của HTTP client, nếu không có sẽ sử dụng chiến lược mặc định
  • Timeout: Cấu hình thời gian timeout của request
  • Jar: Cấu hình liên quan đến Cookie
  • CheckRedirect: Cấu hình chuyển hướng

Ví dụ đơn giản

go
func main() {
  client := &http.Client{}
  request, _ := http.NewRequest("GET", "https://golang.org", nil)
  resp, _ := client.Do(request)
  defer resp.Body.Close()
}

Thêm header

go
func main() {
   client := &http.Client{}
   request, _ := http.NewRequest("GET", "https://golang.org", nil)
   request.Header.Add("Authorization","123456")
   resp, _ := client.Do(request)
   defer resp.Body.Close()
}

Một số cấu hình chi tiết ở đây không đề cập nhiều, mời bạn tự tìm hiểu.

Server

Đối với Go, tạo một HTTP server chỉ cần một dòng code.

Tham số đầu tiên là địa chỉ lắng nghe, tham số thứ hai là handler, nếu để rỗng sẽ sử dụng handler mặc định. Hầu hết các trường hợp sử dụng handler mặc định DefaultServeMux là đủ.

go
http.ListenAndServe("localhost:8080", nil)

Tùy chỉnh

Tất nhiên cũng có thể tùy chỉnh cấu hình một server

go
func main() {
   server := &http.Server{
      Addr:              ":8080",
      Handler:           nil,
      TLSConfig:         nil,
      ReadTimeout:       0,
      ReadHeaderTimeout: 0,
      WriteTimeout:      0,
      IdleTimeout:       0,
      MaxHeaderBytes:    0,
      TLSNextProto:      nil,
      ConnState:         nil,
      ErrorLog:          nil,
      BaseContext:       nil,
      ConnContext:       nil,
   }
   server.ListenAndServe()
}

Một số cấu hình chi tiết mời bạn tự tìm hiểu.

Route

Trước hết cần tùy chỉnh một cấu trúc thực hiện phương thức ServeHTTP(ResponseWriter, *Request) trong interface Handler, sau đó gọi hàm http.handle() là được

go
func main() {
   http.Handle("/index", &MyHandler{})
   http.ListenAndServe(":8080", nil)
}

type MyHandler struct {
}

func (h *MyHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
   fmt.Println("my implement")
}

Nhưng mỗi lần đều phải tùy chỉnh một cấu trúc sẽ rất phức tạp, cũng có thể sử dụng trực tiếp hàm http.handlerFunc, chúng ta chỉ cần viết hàm xử lý là được, không cần tạo cấu trúc. Bên trong nó sử dụng loại adapter HandlerFunc, HandlerFunc là một loại adapter, cho phép sử dụng hàm thông thường làm HTTP handler. Nếu f là hàm có chữ ký phù hợp, HandlerFunc(f) là Handler gọi f.

go
func main() {
   http.HandleFunc("/index", func(responseWriter http.ResponseWriter, request *http.Request) {
      fmt.Println(responseWriter, "index")
   })
   http.ListenAndServe(":8080", nil)
}

ServerMux là cấu trúc cốt lõi, thực hiện các phương thức cơ bản, DefaultServeMux là instance mặc định.

Reverse Proxy

Gói http cung cấp chức năng reverse proxy sẵn sàng sử dụng

go
func main() {
   http.HandleFunc("/forward", func(writer http.ResponseWriter, request *http.Request) {
      director := func(request *http.Request) {
         request.URL.Scheme = "https"
         request.URL.Host = "golang.org"
         request.URL.Path = "index"
      }

      proxy := httputil.ReverseProxy{Director: director}
      proxy.ServeHTTP(writer, request)

   })

   http.ListenAndServe(":8080", nil)
}

Code trên sẽ chuyển tiếp tất cả request đến https://golang.org/index.

Golang by www.golangdev.cn edit