Метод http.Client.Do
Метод http.Client.Do выполняет HTTP-запрос,
представленный объектом http.Request,
и возвращает объект http.Response содержащий
ответ от сервера. Первым параметром метод принимает
указатель на структуру http.Request, которую
необходимо создать с помощью функции
http.NewRequest или
http.NewRequestWithContext. Метод позволяет
полностью контролировать процесс выполнения запроса,
включая заголовки, тело и таймауты.
Синтаксис
client.Do(req)
где client - объект типа http.Client,
req - указатель на http.Request.
Метод возвращает два значения: указатель на
http.Response и ошибку.
Пример
Давайте выполним GET-запрос к тестовому API и выведем код ответа и тело ответа:
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://httpbin.org/get", nil)
if err != nil {
panic(err)
}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
fmt.Println("Status:", res.StatusCode)
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}
Пример
Давайте выполним POST-запрос с отправкой JSON-данных
и добавим заголовок Content-Type:
package main
import (
"bytes"
"fmt"
"io"
"net/http"
)
func main() {
client := &http.Client{}
jsonData := []byte(`{"name": "John", "age": 30}`)
req, err := http.NewRequest(
"POST",
"https://httpbin.org/post",
bytes.NewBuffer(jsonData),
)
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}
Пример
Давайте обработаем ошибки, которые могут возникнуть при выполнении запроса, включая сетевые ошибки и ошибки статуса ответа:
package main
import (
"fmt"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://invalid-url.example", nil)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
res, err := client.Do(req)
if err != nil {
fmt.Println("Error executing request:", err)
return
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
fmt.Println("Unexpected status:", res.StatusCode)
return
}
fmt.Println("Request successful")
}
Пример
Давайте используем метод http.Client.Do
с контекстом для управления таймаутами
и отменой запроса:
package main
import (
"context"
"fmt"
"net/http"
"time"
)
func main() {
client := &http.Client{}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(
ctx,
"GET",
"https://httpbin.org/delay/3",
nil,
)
if err != nil {
panic(err)
}
res, err := client.Do(req)
if err != nil {
fmt.Println("Error:", err)
return
}
defer res.Body.Close()
fmt.Println("Status:", res.StatusCode)
}
Результат выполнения кода:
"Status: 200"
Смотрите также
-
метод
http.Client.Get,
который выполняет GET-запрос более простым способом -
метод
http.Client.Post,
который выполняет POST-запрос с отправкой данных -
метод
http.Client.Head,
который выполняет HEAD-запрос без получения тела -
функцию
http.NewRequestWithContext,
которая создает запрос с поддержкой контекста