Concepto clave
En el desarrollo de APIs REST con gorilla/mux, las rutas y los métodos HTTP son los cimientos sobre los que construyes tu microservicio. Piensa en tu API como un sistema de correos: las rutas son las direcciones (como /usuarios o /productos/123) y los métodos HTTP (GET, POST, PUT, DELETE) son las instrucciones sobre qué hacer en esa dirección (recoger un paquete, dejar uno nuevo, actualizar información, o eliminar algo).
gorilla/mux es un enrutador que te permite definir estas rutas de manera flexible y poderosa, con soporte para variables en las rutas (como {id}), validación de patrones, y subrutas. A diferencia del enrutador estándar de Go, gorilla/mux ofrece características avanzadas como coincidencia de rutas basada en métodos HTTP específicos, lo que es esencial para construir APIs RESTful limpias y mantenibles.
Cómo funciona en la práctica
Imagina que estás construyendo un microservicio para gestionar usuarios. Primero, importas gorilla/mux y creas un nuevo enrutador. Luego, defines rutas que mapean URLs a funciones manejadoras. Por ejemplo, para manejar una solicitud GET a /usuarios, registras una ruta con router.HandleFunc("/usuarios", getUsuarios).Methods("GET"). Esto asegura que solo las solicitudes GET a esa ruta sean manejadas por la función getUsuarios.
Paso a paso: 1) Inicializa el enrutador con mux.NewRouter(). 2) Define rutas usando HandleFunc, especificando el patrón de la ruta y la función manejadora. 3) Asocia métodos HTTP con .Methods() para seguir las convenciones REST. 4) Sirve el enrutador con el servidor HTTP estándar de Go. Esto crea una API donde cada endpoint responde solo a los métodos adecuados, mejorando la claridad y seguridad.
Código en acción
Aquí tienes un ejemplo funcional de un microservicio básico con gorilla/mux que maneja operaciones CRUD para usuarios:
package main
import (
"encoding/json"
"log"
"net/http"
"github.com/gorilla/mux"
)
type Usuario struct {
ID string `json:"id"`
Nombre string `json:"nombre"`
}
var usuarios = []Usuario{{ID: "1", Nombre: "Ana"}}
func getUsuarios(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(usuarios)
}
func main() {
router := mux.NewRouter()
router.HandleFunc("/usuarios", getUsuarios).Methods("GET")
router.HandleFunc("/usuarios/{id}", getUsuario).Methods("GET")
router.HandleFunc("/usuarios", crearUsuario).Methods("POST")
router.HandleFunc("/usuarios/{id}", actualizarUsuario).Methods("PUT")
router.HandleFunc("/usuarios/{id}", eliminarUsuario).Methods("DELETE")
log.Fatal(http.ListenAndServe(":8080", router))
}Antes de refactorizar, podrías tener rutas sin validación de métodos, lo que lleva a comportamientos inesperados. Después, con gorilla/mux, cada ruta está claramente definida con su método HTTP, como se muestra arriba. Aquí está la función getUsuario para completar el ejemplo:
func getUsuario(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := vars["id"]
for _, usuario := range usuarios {
if usuario.ID == id {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(usuario)
return
}
}
http.Error(w, "Usuario no encontrado", http.StatusNotFound)
}Errores comunes
- No especificar métodos HTTP: Olvidar usar
.Methods()puede hacer que una ruta responda a todos los métodos, violando los principios REST y causando problemas de seguridad. Siempre asocia métodos explícitos. - Mal manejo de variables de ruta: No validar o usar incorrectamente variables como
{id}puede llevar a errores en tiempo de ejecución. Usamux.Vars(r)para acceder a ellas de manera segura. - Rutas ambiguas: Definir rutas como
/usuarios/{id}y/usuarios/nuevosin un orden claro puede causar conflictos. gorilla/mux evalúa rutas en el orden de registro, así que registra rutas específicas antes de las genéricas. - Ignorar el tipo de contenido: No establecer
Content-Type: application/jsonen las respuestas puede confundir a los clientes. Siempre configura los headers apropiados. - No manejar errores HTTP: Devolver siempre código 200 OK, incluso en errores, es una mala práctica. Usa
http.Erroro códigos de estado HTTP apropiados como 404 o 400.
Checklist de dominio
- Puedo definir rutas con gorilla/mux usando
HandleFuncy asociarlas con métodos HTTP específicos. - Sé cómo acceder y usar variables de ruta (ej.,
{id}) en mis manejadores conmux.Vars. - Entiendo la importancia del orden de registro de rutas para evitar ambigüedades.
- Configuro correctamente los headers HTTP, como
Content-Type, en mis respuestas JSON. - Manejo errores devolviendo códigos de estado HTTP apropiados (ej., 404 para no encontrado).
- Puedo crear subrutas con
PathPrefixo agrupar rutas relacionadas para una mejor organización. - He probado mis rutas con herramientas como curl o Postman para verificar que responden solo a los métodos esperados.
Implementa un CRUD completo para productos usando gorilla/mux
En este ejercicio, construirás un microservicio REST para gestionar productos, aplicando los conceptos de rutas y métodos HTTP con gorilla/mux. Sigue estos pasos:
- Crea un nuevo proyecto Go e instala gorilla/mux con
go get github.com/gorilla/mux. - Define una estructura
Productocon campos:ID(string),Nombre(string), yPrecio(float64). - Inicializa un enrutador gorilla/mux y define las siguientes rutas RESTful:
- GET
/productos- Devuelve la lista de todos los productos. - GET
/productos/{id}- Devuelve un producto específico por ID. - POST
/productos- Crea un nuevo producto (usa JSON en el cuerpo de la solicitud). - PUT
/productos/{id}- Actualiza un producto existente por ID. - DELETE
/productos/{id}- Elimina un producto por ID.
- GET
- Implementa las funciones manejadoras para cada ruta, usando un slice en memoria para almacenar productos. Asegúrate de manejar errores (ej., producto no encontrado) con códigos HTTP apropiados.
- Prueba tu API con curl o Postman: envía solicitudes a cada endpoint y verifica las respuestas.
- Usa
json.NewDecoder(r.Body).Decode(&producto)para parsear JSON en las solicitudes POST y PUT. - Para el manejo de variables de ruta, recuerda extraer el ID con
vars := mux.Vars(r)y validar su existencia. - En las respuestas, establece
w.Header().Set("Content-Type", "application/json")para asegurar que el cliente interprete correctamente los datos.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.