Пакет http в Go
Пакет net/http в стандартной библиотеке Go очень эффективен и предоставляет полную реализацию HTTP-клиента и сервера. Можно создать очень простой HTTP-сервер всего за несколько строк кода.
Почти все веб-фреймворки на Go являются обёртками или модификациями существующего пакета http, поэтому настоятельно рекомендуется изучить пакет http перед изучением других фреймворков.
Пример Get
Здесь не будет подробно описываться информация о Http, желающие узнать больше могут обратиться к поисковым системам.
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))
}Простой вызов функций из пакета Http позволяет отправлять простые запросы, возвращая указатель и ошибку. После вызова необходимо вручную закрыть соединение.
Пример 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()
}Клиент
Обычно мы не используем вышеупомянутые методы напрямую, а настраиваем собственный клиент для более детализированных требований. Для этого используется структура http.Client{}, которая предоставляет четыре конфигурации:
Transport: конфигурация, связанная с передачей данных HTTP-клиента, если нет — используется стратегия по умолчаниюTimeout: конфигурация времени ожидания запросаJar: конфигурация, связанная с CookieCheckRedirect: конфигурация перенаправления
Простой пример
func main() {
client := &http.Client{}
request, _ := http.NewRequest("GET", "https://golang.org", nil)
resp, _ := client.Do(request)
defer resp.Body.Close()
}Добавление заголовка
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()
}Здесь не будет подробно описываться подробные конфигурации, желающие могут узнать самостоятельно.
Сервер
Для Go создание HTTP-сервера требует всего одной строки кода.
Первый параметр — адрес прослушивания, второй параметр — обработчик, если он равен nil, используется обработчик по умолчанию. В большинстве случаев достаточно использовать обработчик по умолчанию DefaultServeMux.
http.ListenAndServe("localhost:8080", nil)Настройка
Конечно, можно настроить собственный сервер:
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()
}Подробные конфигурации можно узнать самостоятельно.
Маршрутизация
Сначала необходимо определить структуру, реализующую метод ServeHTTP(ResponseWriter, *Request) интерфейса Handler, затем вызвать функцию http.Handle():
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")
}Однако каждый раз определять структуру очень трудоёмко, поэтому можно использовать функцию http.HandleFunc, где нужно написать только функцию обработки, не создавая структуру. Внутри используется тип адаптера HandlerFunc, где HandlerFunc — это адаптер, позволяющий использовать обычные функции в качестве обработчиков HTTP. Если f — функция с соответствующей сигнатурой, то HandlerFunc(f) — это Handler, вызывающий f.
func main() {
http.HandleFunc("/index", func(responseWriter http.ResponseWriter, request *http.Request) {
fmt.Println(responseWriter, "index")
})
http.ListenAndServe(":8080", nil)
}ServerMux — это основная структура, реализующая базовые методы, DefaultServeMux — экземпляр по умолчанию.
Обратный прокси
Пакет http предоставляет готовую функцию обратного прокси:
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)
}Приведённый выше код будет перенаправлять все запросы на https://golang.org/index.
