Ir al contenido principal

Arquitectura de Middleware de Mensajería

Esta guía detalla la construcción de un sistema en Go diseñado para ser multitenant y desacoplado. La clave de este diseño es que el núcleo del servidor no depende de configuraciones estáticas, permitiendo gestionar múltiples clientes y proveedores de forma dinámica.

El servidor no "conoce" a los clientes de antemano. Recibe la identidad (Token) en tiempo de ejecución, procesa el contrato de datos y delega la respuesta.

1. Estructura de Directorios Estándar

Siguiendo el Standard Go Project Layout, organizamos el código para separar la infraestructura de la lógica de negocio.

project-root/
├── cmd/api/             # Punto de entrada (main.go)
├── internal/            # Código privado del proyecto
│   ├── handlers/        # Controladores HTTP (Webhook Receptor)
│   ├── providers/       # Adaptadores de API (Envío de mensajes)
│   ├── models/          # Estructuras de datos (Contratos JSON)
│   └── services/        # Lógica de procesamiento
└── .env                 # Variables globales

2. El Webhook Receptor (Entrada Dinámica)

Para que el sistema sea agnóstico, el Webhook extrae el Token directamente de la URL. Esto permite que un solo endpoint atienda a infinitos clientes sin necesidad de reiniciar el servicio.

Efectividad: Usar json.NewDecoder procesa el body como un flujo (stream), optimizando el uso de memoria RAM bajo alta carga.
 func WebhookHandler(w http.ResponseWriter, r *http.Request) { // 1. Validar método if r.Method != http.MethodPost { http.Error(w, "Method not allowed", 405) return }

// 2. Extracción dinámica del Token (Agnosticismo)
token := r.URL.Query().Get("token")
if token == "" {
    http.Error(w, "Unauthorized: Token missing", 401)
    return
}

// 3. Decodificación eficiente
var payload models.WebhookRequest
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
    http.Error(w, "Bad Request", 400)
    return
}

// 4. Delegación a la lógica de negocio
if payload.Event == "Message" {
    go providers.SendMessage(payload.Data.From, "Procesado", token)
}

w.WriteHeader(http.StatusOK)
} 

3. Adaptador de Envío (Inyección de Dependencias)

La función de envío no utiliza variables globales para el Token. Lo recibe como parámetro, lo que la hace pura y reutilizable.

 func SendMessage(target, text, clientToken string) error { apiURL := os.Getenv("API_URL") + "/send"

// Crear el contrato de salida
body := models.MessageResponse{
    Phone: target,
    Body:  text,
}

// ... lógica de marshalling ...

req, _ := http.NewRequest("POST", apiURL, bytes.NewBuffer(data))

// Inyectar el token recibido dinámicamente
req.Header.Set("Token", clientToken)
req.Header.Set("Content-Type", "application/json")

client := &http.Client{Timeout: 10 * time.Second}
_, err := client.Do(req)
return err
} 
Gestión de Errores: En Go, los errores son valores. Siempre se debe capturar el retorno de client.Do(req) para evitar que el fallo de un cliente afecte el flujo de los demás.

4. Estándares Técnicos Aplicados

  • Visibilidad: Uso de Mayúsculas para exportar funciones entre paquetes (ej. SendMessage).
  • Concurrencia: Uso de go routine para procesar respuestas sin bloquear la recepción del Webhook.
  • Desacoplamiento: El Handler no sabe cómo se envía el mensaje, y el Proveedor no sabe de dónde vino el mensaje. Solo comparten Models.
Resultado Final: Un sistema capaz de escalar horizontalmente, donde agregar un nuevo cliente es tan simple como enviarle una URL con su propio token.

Comentarios

Entradas populares de este blog

Instalar Evolution API en Docker con Redis y PostgreSQL Local

Instalar Evolution API en Docker con Redis y PostgreSQL Local En este tutorial vamos a levantar Evolution API usando Docker , con soporte de Redis para sesiones y PostgreSQL local para almacenar datos de manera persistente y compartida entre varios usuarios. 1. Estructura del proyecto Crea una carpeta para tu proyecto y colócate en ella: mkdir -p ~/docker/evolution-api cd ~/docker/evolution-api 2. Archivo docker-compose.yml Este compose levanta Redis y Evolution API : version: "3.9" services: # ✅ SERVICIO REDIS redis: container_name: evolution_redis image: redis:7-alpine restart: unless-stopped ports: - "6379:6379" volumes: - redis_data:/data command: redis-server --save 60 1 --loglevel warning # ✅ SERVICIO EVOLUTION API evolution-api: container_name: evolution_api image: atendai/evolution-api restart: unless-stopped ports: - "8085:8080" env_file: - .env ...

Instalación y Configuración de MySQL 5.7 en Ubuntu 24.04 LTS

Instalar MySQL 5.7 en Ubuntu 24.04 1. Descargar e instalar MySQL Copiar mkdir ~/mysql57 cd ~/mysql57 wget https://cdn.mysql.com/archives/mysql-5.7/mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz tar -zxvf mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz sudo mv mysql-5.7.44-linux-glibc2.12-x86_64 /usr/local/mysql sudo ln -s /usr/local/mysql/bin/mysql /usr/local/bin/mysql 2. Instalar dependencias necesarias IMPORTANTE: Se descargan las versiones nuevas de las librerías y se las vincula con las librerías que necesita MySQL. Copiar sudo apt update # Reemplazo de libaio sudo apt install libaio1t64 # Reemplazo de libtinfo y ncurses sudo apt install libtinfo6 libncurses6 Copiar # Crear los enlaces simbólicos sudo ln -sf /usr/lib/x86_64-linux-gnu/libaio.so.1t64 /usr/lib/libaio.so.1 sudo ln -sf /usr/lib/x86_64-linux-gnu/libtinfo.so.6 /usr/lib/x86_64-linux-gnu/libtinfo.so.5 sudo ln -sf /usr/lib/x86_64-linux-gnu/libncurses.so.6 /usr/lib/x86_64...

Instalar Jasper Studio 6.21 para Ubuntu 24.04

Instalar js-studiocomm_6.21.3 en Ubuntu 24.4 Para instalar Jaspersoft Studio en Ubuntu 24.4, sigue estos pasos: 1. Descargar Jasper Studio Descarga la versión js-studiocomm_6.21.3 desde el siguiente enlace: Jaspersoft Studio 6.21.3 2. Crear el directorio de instalación mkdir /opt/jasperstudio 3. Mover el archivo descargado mv /dir_descarga/js-studiocomm_6.21.3_linux_x86_64.tgz /opt/jasperstudio/ cd /opt/jasperstudio 4. Extraer el archivo tar -xvzf js-studiocomm_6.21.3_linux_x86_64.tgz cd js-studiocomm_6.21.3 5. Ejecutar Jaspersoft Studio ./Jaspersoft\ Studio 6. Crear acceso directo en el escritorio Para facilitar el acceso, crea un archivo .desktop en el escritorio: gedit ~/Escritorio/jaspersoft-studio.desktop En el archivo jaspersoft-studio.desktop , agrega lo siguiente: [Desktop Entry] Version=1.0 Ty...