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

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 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 ...

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...