Manejando Request HTTP

Clase 32 de 42Curso Práctico de Go: Creación de un Servidor Web

Contenido del curso

Construyendo un Servidor Web

Resumen

Separar responsabilidades es fundamental cuando construyes un servidor HTTP en Go. En lugar de escribir toda la lógica dentro del router, lo correcto es delegar el trabajo a handlers independientes que se encarguen de responder cada ruta. Aquí se explica cómo crear un handler, cómo buscar rutas dentro de un map y cómo preparar tu servidor para asociar rutas con sus respectivos manejadores.

¿Por qué separar los handlers del router?

El router tiene una única responsabilidad: saber qué handler está asociado a qué ruta. Mezclar la lógica de respuesta directamente en el router rompe este principio. Por eso, se crea un archivo separado llamado handlers.go donde vivirán todas las funciones encargadas de manejar las peticiones [00:22].

Esta separación mejora la organización del código y facilita el mantenimiento a medida que el servidor crece con más rutas y funcionalidades.

¿Cómo se crea un handler en Go?

Un handler es una función que recibe dos parámetros esenciales [01:00]:

  • http.ResponseWriter: el escritor que permite responder al cliente.
  • *http.Request: el objeto que contiene toda la información de la petición, como parámetros enviados y la ruta que se intenta acceder.

El archivo comienza con package main y luego se define la función handleRoute. Para escribir la respuesta, se utiliza fmt.Fprint, que recibe el escritor y el mensaje que se desea enviar al cliente [01:45]:

go package main

import ( "fmt" "net/http" )

func handleRoute(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello world") }

La función fmt.Fprint es parte de la librería estándar de Go y funciona de forma similar a fmt.Print, pero permite dirigir la salida hacia cualquier escritor, en este caso el http.ResponseWriter.

¿Cómo asociar un handler a una ruta específica?

Una vez creado el handler, el siguiente paso es que el router sea capaz de encontrarlo. Para esto se crea una función llamada FindHandler dentro del struct del router, utilizando un receiver [02:18].

Esta función recibe un path de tipo string, que representa la ruta solicitada (por ejemplo /, /api o /home). Ese path se usa como llave para buscar dentro del map de reglas.

¿Cómo verificar si una llave existe en un map de Go?

Un map en Go ofrece dos formas de acceder a sus valores [02:55]. La primera devuelve solo el valor. La segunda, más poderosa, devuelve dos valores: el contenido asociado a la llave y un booleano que indica si esa llave existe o no.

Este patrón se conoce como la comma ok idiom y resulta extremadamente útil para decidir si se debe retornar el handler correspondiente o un error 404 cuando la ruta no se encuentra:

go func (rt *Router) FindHandler(path string) (Handler, bool) { handler, exist := rt.rules[path] return handler, exist }

  • handler: almacena el valor que devuelve el map para esa llave.
  • exist: es true si la llave existe dentro del map, o false si no se encontró.

Gracias a este enfoque, el router puede retornar múltiples valores desde una sola función, algo que Go permite de forma nativa y que simplifica el manejo de errores y condiciones.

¿Qué falta para completar el registro de rutas?

Hasta este punto, el handler está creado y el router puede buscar rutas en su map de reglas. Sin embargo, todavía no existe un mecanismo para registrar rutas y asociarlas a handlers específicos [04:08].

Los pasos completados son:

  • Crear handlers.go con la función handleRoute.
  • Implementar FindHandler con búsqueda en el map y validación de existencia.
  • Retornar tanto el handler como el estado de la búsqueda.

El siguiente paso será modificar el server para que permita agregar rutas dinámicamente, por ejemplo asociar /api al handler correspondiente. Esto cerrará el ciclo completo entre registro de rutas, búsqueda y ejecución del handler adecuado.

¿Has trabajado con maps y múltiples valores de retorno en Go? Comparte tu experiencia y las dudas que te hayan surgido.