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.
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
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 địnhTimeout: Cấu hình thời gian timeout của requestJar: Cấu hình liên quan đến CookieCheckRedirect: Cấu hình chuyển hướng
Ví dụ đơn giản
func main() {
client := &http.Client{}
request, _ := http.NewRequest("GET", "https://golang.org", nil)
resp, _ := client.Do(request)
defer resp.Body.Close()
}Thêm header
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à đủ.
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
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
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.
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
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.
