Cliente HTTP en Go: haciendo solicitudes correctamente de la A a la Z

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Cliente HTTP en Go: haciendo solicitudes correctamente de la A a la Z



Go (Golang) es un lenguaje conocido por su simplicidad y rendimiento, especialmente en el área de programación de redes. El paquete integrado net/http proporciona un cliente HTTP potente y flexible, adecuado tanto para solicitudes simples como para sistemas complejos de alta carga. En este artículo, analizaremos cómo usar correctamente el cliente HTTP en Go, desde las solicitudes básicas hasta configuraciones avanzadas.



1. Fundamentos: creación y ejecución de solicitudes simples



La forma más sencilla de hacer una solicitud HTTP en Go es usar las funciones auxiliares del paquete net/http, como http.Get y http.Post. Sin embargo, para código de producción, se recomienda crear explícitamente el cliente y la solicitud.



Solicitud GET básica:



package main

import ( "fmt" "io/ioutil" "net/http")

func main() { // Creamos un nuevo cliente client := &http.Client{}

// Creamos la solicitud req, err := http.NewRequest("GET", "https://api.example.com/data", nil) if err != nil { fmt.Println("Error al crear la solicitud:", err) return }

// Ejecutamos la solicitud resp, err := client.Do(req) if err != nil { fmt.Println("Error al ejecutar la solicitud:", err) return } defer resp.Body.Close()

// Leemos el cuerpo de la respuesta body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("Error al leer la respuesta:", err) return }

fmt.Println("Estado:", resp.Status) fmt.Println("Cuerpo:", string(body))}


Solicitud POST con cuerpo JSON:



package main

import ( "bytes" "encoding/json" "fmt" "net/http")

type Payload struct { Name string `json:"name"` Email string `json:"email"`}

func main() { payload := Payload{Name: "John", Email: "john@example.com"} jsonData, _ := json.Marshal(payload)

client := &http.Client{} req, err := http.NewRequest("POST", "https://api.example.com/users", bytes.NewBuffer(jsonData)) if err != nil { fmt.Println("Error:", err) return }

// Establecemos los encabezados req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer your-token")

resp, err := client.Do(req) if err != nil { fmt.Println("Error:", err) return } defer resp.Body.Close()

fmt.Println("Estado:", resp.Status)}


2. Gestión de tiempos de espera y contextos



Uno de los errores más comunes es la falta de tiempos de espera. Sin ellos, su cliente puede quedarse bloqueado indefinidamente esperando una respuesta del servidor. En Go, hay dos formas principales de gestionar el tiempo de espera.



Tiempo de espera a nivel de cliente:



client := &http.Client{    Timeout: 10 * time.Second, // Tiempo de espera total para toda la solicitud}


Tiempo de espera usando contexto (recomendado):



ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()

req, err := http.NewRequestWithContext(ctx, "GET", "https://api.example.com/data", nil)if err != nil { log.Fatal(err)}

resp, err := client.Do(req)if err != nil { // Verificamos si se excedió el tiempo de espera if errors.Is(err, context.DeadlineExceeded) { fmt.Println("La solicitud superó el tiempo de espera") } else { fmt.Println("Error:", err) } return}defer resp.Body.Close()


El uso del contexto brinda más flexibilidad: puede cancelar la solicitud en cualquier momento (por ejemplo, al cerrar la aplicación) y pasar valores a través del contexto.



3. Manejo de errores y reintentos



La red no es confiable, por lo que su cliente debe estar preparado para fallos temporales.

Blogs

Book Recommendations