What's the difference between timeout set in http.Client and timeout set in request's context?
I've seen 2 ways of setting timeout in http client.
First:
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "http://localhost:8080", nil)
Second:
client := http.Client{
Timeout: 2 * time.Second,
}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
when to use one over the other?
Both can achieve the same thing which is to terminate the request due to timeout.
But using context is the preferred way as it's made for this task. The field timeout exist before context added to Go. You have to pick one for timeout at the time creating the request as the the request will pick the smaller timeout to be applied, rendering other useless. In this case the preferable method is using the context timeout as you have more control over it, you can use cancel without specifying timeout in case you want to cancel the request by logic decision. Using context you can also pass any values through it describing request scope values.
Using context is request specific, while using the Client timeout might be applied to all request pass to
Do
method client has. If you want to specialise your deadline/timeout to each request then use context, otherwise if you want 1 timeout for every outbound request then using client timeout is enough.You can also read about it here Specify timeout when tracing HTTP request in Go