SAP CAP + RabbitMQ: Cómo hacer que tu backend hable con colas de mensajes

SAP CAP + RabbitMQ: Cómo hacer que tu backend hable con colas de mensajes


¿Desacoplar CAP? ¿Que en vez de peticiones directas, se manden mensajitos por una cola y así evitar cuellos de botella? Pues hoy te voy a contar cómo integrar SAP CAP con RabbitMQ, una de las soluciones de mensajería más usadas en el mundillo.



¿Qué vamos a montar?

  1. Un proyecto SAP CAP (Node.js)
  2. Un servidor RabbitMQ local o en Docker
  3. Una integración para enviar mensajes desde CAP a una cola en RabbitMQ
    Opcional: un consumer para leer esos mensajes (porque está guay ver qué se recibe).



Requisitos previos

  1. Node.js instalado
  2. Docker (para RabbitMQ)
  3. Proyecto CAP creado (cds init sap-cap-rabbitmq)
  4. Cliente AMQP para Node.js (usaremos amqplib)
npm install amqplib
Enter fullscreen mode

Exit fullscreen mode



Levantando RabbitMQ con Docker

Si no tienes un RabbitMQ montado, en 5 segundos lo tienes:

docker run -d --hostname my-rabbit --name some-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3-management
Enter fullscreen mode

Exit fullscreen mode

La consola de administración estará en: http://localhost:15672
Usuario: guest / Contraseña: guest



Integrando SAP CAP con RabbitMQ

Vamos a crear un servicio en CAP que envíe mensajes a RabbitMQ.

  1. Crea un módulo JS para la conexión
    /srv/cat-service.js
const cds = require('@sap/cds');
const amqp = require('amqplib');

module.exports = cds.service.impl(async function () {

    this.on('sendMessage', async (req) => {
        const { queue, message } = req.data;

        try {
            // Conectar a RabbitMQ
            const connection = await amqp.connect('amqp://localhost');
            const channel = await connection.createChannel();
            await channel.assertQueue(queue, { durable: false });

            console.log(`📤 Enviando mensaje a ${queue}...`);

            // Enviar el mensaje a la cola una vez
            channel.sendToQueue(queue, Buffer.from(message));
            console.log(`📤 Mensaje enviado a ${queue}: ${message}`);

            // Cerrar conexión
            await channel.close();
            await connection.close();
            console.log('🔌 Conexión cerrada');

            return `Mensaje enviado a ${queue}`;
        } catch (error) {
            console.error('❌ Error enviando mensaje:', error);
            return 'Error al enviar el mensaje';
        }
    });


});
Enter fullscreen mode

Exit fullscreen mode

  1. Define la acción en tu CDS

/srv/cat-service.cds

using myapp from '../db/schema';

service MensajeriaService {
    entity Mensajes as projection on myapp.Mensajes;
    action sendMessage(queue: String, message: String) returns String;
}
Enter fullscreen mode

Exit fullscreen mode

  1. Define la entidad mensaje
namespace myapp;

entity Mensajes {
    key ID : UUID;
    queue  : String;
    message: String;
}
Enter fullscreen mode

Exit fullscreen mode

  1. Testea enviando un POST al servicio
curl -X POST http://localhost:4004/catalog/sendToQueue -H "Content-Type: application/json" -d '{"text": "¡Hola Rabbit!"}'
Enter fullscreen mode

Exit fullscreen mode

Verifica el mensaje en la consola de RabbitMQ

Entra en http://localhost:15672, busca la cola my_queue y verás tu mensaje esperando.

Opcional: Monta otro servicio para consumir de la cola de RabbitMQ, aquí te dejo un código de ejemplo.

const cds = require('@sap/cds');
const amqp = require('amqplib');

module.exports = cds.service.impl(async function () {
    const queue = 'myQueue'; // Nombre de la cola en RabbitMQ

    async function consumeMessages() {
        try {
            // Conectar a RabbitMQ
            const connection = await amqp.connect('amqp://localhost');
            const channel = await connection.createChannel();
            await channel.assertQueue(queue, { durable: false });

            console.log(`📥 [SAP CAP] Esperando mensajes en la cola: ${queue}...`);

            // Consumir mensajes de la cola
            channel.consume(queue, async (msg) => {
                if (msg !== null) {
                    const messageContent = msg.content.toString();
                    console.log(`✅ Mensaje recibido: ${messageContent}`);

                    // Aquí puedes procesar el mensaje, por ejemplo, guardarlo en la base de datos
                    const db = await cds.connect.to('db');
                    await db.run(INSERT.into('Mensajes').entries({
                        ID: cds.utils.uuid(),
                        queue: queue,
                        message: messageContent
                    }));

                    // Confirmar procesamiento del mensaje
                    channel.ack(msg);
                }
            });

        } catch (error) {
            console.error('❌ Error en el consumidor de RabbitMQ:', error);
        }
    }

    // Ejecutar el consumidor cuando arranque el servicio CAP
    consumeMessages();
});
Enter fullscreen mode

Exit fullscreen mode



Conclusión

Y listo. Ya tienes SAP CAP enviando mensajes a RabbitMQ. Esto viene genial para desacoplar procesos pesados o notificar a otros sistemas.



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *