How do you handle HTTP timeouts with an HTTP client in Go?

In Go, you can handle HTTP timeouts with the help of the net/http package. By default, the http.Client type provided by the package has no timeout set. However, you can set a timeout using the Timeout field of the http.Client type.
HTTP Timeout
Here's an example of setting a timeout of 5 seconds for an HTTP request:

Example

import (
    "net/http"
    "time"
)

func main() {
    // Create an http client with a timeout of 5 seconds
    client := &http.Client{
        Timeout: time.Second * 5,
    }

    // Send an HTTP request
    resp, err := client.Get("http://example.com")
    if err != nil {
        // Handle the error
    }

    // Handle the response
    defer resp.Body.Close()
    // ...
}

In this example, we create an http.Client instance and set its Timeout field to time.Second * 5, which is a duration of 5 seconds. This means that if the request takes longer than 5 seconds to complete, the client will cancel the request and return an error.

Note that you can set a timeout for different types of HTTP requests, such as GET, POST, PUT, and DELETE, by using the appropriate method on the http.Client instance. For example, you can use client.Post() to set a timeout for an HTTP POST request.


Example
Here's an example of a simple Go CRUD (Create, Read, Update, Delete) application using HTTP timeouts:

Example

package main

import (
    "fmt"
    "log"
    "net/http"
    "time"
)

func main() {
    // Create a new HTTP client with a timeout of 10 seconds
    client := &http.Client{
        Timeout: 10 * time.Second,
    }

    // Define the endpoints for the CRUD operations
    http.HandleFunc("/create", createHandler(client))
    http.HandleFunc("/read", readHandler(client))
    http.HandleFunc("/update", updateHandler(client))
    http.HandleFunc("/delete", deleteHandler(client))

    // Start the server and log any errors
    log.Fatal(http.ListenAndServe(":8080", nil))
}

func createHandler(client *http.Client) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // Set the request timeout to 5 seconds
        ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
        defer cancel()

        // Make the request with the client
        _, err := client.PostContext(ctx, "http://localhost:8080/create", nil)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }

        // Write the success message to the response
        fmt.Fprint(w, "Create successful")
    }
}

func readHandler(client *http.Client) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // Set the request timeout to 5 seconds
        ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
        defer cancel()

        // Make the request with the client
        _, err := client.GetContext(ctx, "http://localhost:8080/read")
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }

        // Write the success message to the response
        fmt.Fprint(w, "Read successful")
    }
}

func updateHandler(client *http.Client) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // Set the request timeout to 5 seconds
        ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
        defer cancel()

        // Make the request with the client
        _, err := client.PutContext(ctx, "http://localhost:8080/update", nil)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }

        // Write the success message to the response
        fmt.Fprint(w, "Update successful")
    }
}

func deleteHandler(client *http.Client) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // Set the request timeout to 5 seconds
        ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
        defer cancel()

        // Make the request with the client
        _, err := client.DeleteContext(ctx, "http://localhost:8080/delete")
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }

        // Write the success message to the response
        fmt.Fprint(w, "Delete successful")
    }
}

This code creates an HTTP client with a timeout of 10 seconds, and then defines four endpoint handlers for the CRUD operations. Each handler sets a request timeout of 5 seconds using the request's context, and then makes a request to the corresponding endpoint using the HTTP client. If the request fails, an error response is written to the HTTP response. If the request succeeds, a success message is written to the HTTP response.


Most Helpful This Week