Оба подхода работают, но на разных уровнях. http.Client.Timeout задает глобальный таймаут клиента, а context.WithTimeout - таймаут для конкретного запроса.
client := &http.Client{
Timeout: 10 * time.Second, // таймаут на весь запрос
}
resp, err := client.Get("https://api.example.com/data")
// покрывает: DNS, подключение, TLS, отправку, чтение ответа
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
resp, err := client.Do(req)
Client.Timeout - дефолтный таймаут для всех запросов этого клиентаcontext.WithTimeout - когда разные запросы требуют разных таймаутовclient := &http.Client{
Timeout: 30 * time.Second,
Transport: &http.Transport{
DialContext: (&net.Dialer{Timeout: 5 * time.Second}).DialContext,
TLSHandshakeTimeout: 5 * time.Second,
ResponseHeaderTimeout: 10 * time.Second,
},
}
http.Get() использует http.DefaultClient без таймаута - в production это опасно, запрос может висеть бесконечно.