Petición POST, GET, PUT y DELETE en Go con net/http

Golang es un lenguaje utilizado del lado del servidor debido a su simplicidad de uso, potencia y velocidad.

Sin embargo, con Go también se pueden hacer peticiones HTTP. Es decir, Go también puede funcionar como cliente HTTP, no solo como servidor.

Como sabemos, hay 4 métodos básicos para las peticiones HTTP: POST para enviar datos, GET para obtener, PUT para actualizar y DELETE para eliminar.

Peticiones HTTP con Go y net http

En este post veremos ejemplos de cómo hacer estas 4 peticiones con Go usando el paquete net/http para lograr hacer una petición GET, POST, PUT y DELETE usando Golang.

También vamos a ver cómo escribir y enviar encabezados o el código de respuesta (200 para OK, 500 de error, 405 de no permito, etcétera)

El sitio web que vamos a usar para probar será httpbin.org, el cual sirve como espejo para probar que realmente estamos haciendo las peticiones y enviando datos.

Peticiones HTTP con Golang

Voy a explicar lo básico y más abajo dejaré ejemplos.

Para comenzar importa el paquete net/http; es lo único que necesitas para las conexiones HTTP, aunque si vas a codificar con JSON debes importar encoding/json.

Ya veremos en el código cuáles cosas hacen falta. Comenzamos creando un cliente HTTP:

clienteHttp := &http.Client{}

Y también creamos una petición:

peticion, err := http.NewRequest("GET", url, nil)

La petición recibe 3 argumentos: el tipo o verbo, la url y los datos. Si es GET o simplemente no queremos enviar datos pasamos nil.

A la petición le podemos agregar encabezados:

peticion.Header.Add("X-Hola-Mundo", "Ejemplo")

Para realizar la petición (ahora sí hacerla) invocamos al método Do del cliente HTTP:

respuesta, err := clienteHttp.Do(peticion)

En caso de que err sea nil debemos cerrar el cuerpo, podemos usar defer para cerrarlo al final:

defer respuesta.Body.Close()

Para acceder al cuerpo lo leemos con ioutil.ReadAll:

cuerpoRespuesta, err := ioutil.ReadAll(respuesta.Body)

Podemos convertirlo a cadena, pues ReadAll lo devuelve como bytes. Para convertirlo hacemos esto:

respuestaString := string(cuerpoRespuesta)

Si queremos acceder al código de respuesta lo hacemos a través de StatusCode:

log.Printf("Código de respuesta: %d", respuesta.StatusCode)

Los encabezados se encuentran en respuesta.Header en forma de mapa. No hay necesidad de parsear los valores por nosotros, pues ya existe el método Get:

contentType := respuesta.Header.Get("Content-Type")

Sobra decir que podemos escribir la respuesta en un archivo, decodificarla como JSON o ignorarla.

Ahora sí veamos el código de ejemplo.

Petición GET

El código es el siguiente:

No estamos enviando nada en el cuerpo, pues es una petición GET. Si se desea indicar parámetros en la URL simplemente se usa una concatenación.

Probar.

Petición POST

El código queda como a continuación:

Ahora sí enviamos el cuerpo, el cual es un búfer que contiene un dato JSON. Podríamos enviar el JSON directamente como cadena o codificar un struct.

Probar.

Petición PUT

Es casi igual que POST, solo cambia el verbo y la URL para httpbin. Desconozco cuál es la verdadera diferencia pero el código para hacer una petición PUT es el siguiente:

Probar.

Petición DELETE

Aquí entra una discusión que no tiene que ver con Go y es que si al hacer una llamada DELETE se pueden pasar datos en el cuerpo.

En algunos lugares es posible, es decir, algunos servidores lo aceptan, otros no. Yo recomiendo no pasar nada en el cuerpo.

El siguiente código hace una petición HTTP DELETE:

Probar.

Conclusión

Golang funciona como servidor y como cliente HTTP. Podemos hacer múltiples llamadas a otros servidores utilizando el protocolo HTTP y enviando datos.

Personalmente utilicé las peticiones en Go para probar mi servidor. Es decir, programé el servidor y después hice los tests automatizados para probar que el servidor funcionaba.