Notificaciones sencillas en NestJS mediante eventos del lado del servidor para operaciones masivas

Temp mail SuperHeros
Notificaciones sencillas en NestJS mediante eventos del lado del servidor para operaciones masivas
Notificaciones sencillas en NestJS mediante eventos del lado del servidor para operaciones masivas

Entrega de notificaciones simplificada para operaciones de inserción masiva

Imagine que está administrando un sistema en el que a cientos de empleados se les asignan vales según diversos criterios, como departamento, grado o experiencia. Es una tarea colosal notificar a cada empleado de manera eficiente sin causar cuellos de botella en el sistema. 🔔 Este desafío se vuelve aún más desalentador cuando se intenta evitar las complejidades de los sockets o los mecanismos de sondeo.

En tales escenarios, los eventos del lado del servidor (SSE) surgen como una solución poderosa pero sencilla. Al aprovechar SSE en su aplicación NestJS, puede establecer un canal de comunicación en tiempo real para notificar a grupos específicos de empleados según criterios dinámicos. Por ejemplo, cuando se asignan vales al departamento de Ventas, solo esos empleados deben recibir notificaciones, lo que garantiza actualizaciones precisas y significativas.

A lo largo de este artículo, profundizaremos en un ejemplo práctico que demuestra cómo integrar SSE en un proceso de inserción masiva utilizando NestJS. Recorreremos el ciclo de vida, desde la activación de eventos en el backend hasta la escucha de actualizaciones en el frontend, todo ello manteniendo un rendimiento perfecto. 💼

Ya sea que esté desarrollando una herramienta de recursos humanos o una aplicación de finanzas, comprender este flujo de trabajo le permitirá enviar notificaciones personalizadas en tiempo real. Analicemos la simplicidad de SSE y cómo puede mejorar la experiencia del usuario de su aplicación.

Dominio Ejemplo de uso
@Sse Un decorador NestJS utilizado para definir un punto final de eventos del lado del servidor (SSE). Por ejemplo, @Sse('empleado-con vale') configura un punto final para transmitir actualizaciones en tiempo real al cliente.
fromEvent Una función de RxJS que convierte un evento emitido por un Emisor de eventos en una corriente observable. Por ejemplo, fromEvent(this.eventEmitter, 'vale después de agregar') escucha un evento específico.
Observable Un concepto central de RxJS utilizado para gestionar flujos de datos asincrónicos. Es esencial para manejar eventos del lado del servidor en NestJS, como Observable<MessageEvent>.
@InjectQueue Un decorador NestJS que inyecta una instancia de cola, útil para gestionar el procesamiento de trabajos con bibliotecas como Bull. Por ejemplo, @InjectQueue('allotVoucher') proporciona acceso a la cola denominada 'allotVoucher'.
WorkerHost Una clase base de BullMQ que permite definir procesadores de trabajos personalizados en NestJS. Por ejemplo, el AllotVoucherConsumidor la clase se extiende trabajadoranfitrión para realizar trabajos específicos.
@OnWorkerEvent Un decorador solía escuchar eventos específicos del ciclo de vida de un trabajo en cola. Por ejemplo, @OnWorkerEvent('completado') maneja el evento "completado" de un trabajo.
createMany Un comando de Prisma utilizado para insertar varios registros en una base de datos a la vez. Por ejemplo, prisma.cupón de empleado.createMany Agrega todos los bonos de los empleados en una sola operación.
EventSource Una API de JavaScript para recibir eventos enviados por el servidor (SSE) desde el backend. Por ejemplo, nuevo EventSource('http://localhost/vouchered-employee') establece una conexión para la transmisión de datos.
add Un método de colas Bull para agregar un nuevo trabajo a la cola. Por ejemplo, allotVoucherQueue.add('asignar-vale', datos de trabajo) programa un trabajo para su procesamiento.
@OnEvent Un decorador NestJS que escucha eventos específicos emitidos dentro de la aplicación. Por ejemplo, @OnEvent('vale-después de la asignación') desencadena un método cuando se emite este evento.

Notificaciones eficientes con colas y eventos del lado del servidor

Los scripts proporcionados ilustran un sistema en el que se envían notificaciones en tiempo real a los empleados después de la inserción masiva de registros de comprobantes en la base de datos. El proceso comienza en el Controlador de asignación de cupones, que expone un punto final para crear tareas de asignación de cupones. Cuando se crea una tarea, emite un evento llamado vale después de la asignación. Este evento es esencial para desencadenar los pasos siguientes, asegurando que el sistema esté impulsado por eventos y sea modular. Este diseño permite una clara separación de preocupaciones, lo que hace que el sistema sea más mantenible y escalable. 🎯

En la capa de servicio, el Asignar servicio de vales maneja la lógica para poner en cola tareas usando BullMQ. Después de recibir el vale después de la asignación evento, agrega un trabajo a la cola denominada vale de asignación. Esta cola permite el procesamiento asincrónico, lo que garantiza que el sistema siga respondiendo incluso cuando se procesan grandes conjuntos de datos. Por ejemplo, si asigna vales a 200 empleados en el departamento de Ventas, la cola garantiza que la operación no bloquee otras solicitudes. La configuración de la cola incluye opciones como eliminar al completar para mantener Redis limpio una vez finalizado el trabajo.

Los trabajos en cola son procesados ​​por el AllotVoucherConsumidor clase. Aquí se implementa la lógica para identificar a los empleados relevantes e insertar registros de comprobantes en la base de datos. El comando Prisma crearmuchos se utiliza para insertar registros por lotes en el empleadovale tabla, que está optimizada para el rendimiento. Una vez completada la operación de la base de datos, se emite otro evento para notificar a los suscriptores. Este evento garantiza que los empleados solo sean notificados después de que la inserción masiva se haya procesado exitosamente, lo que agrega confiabilidad al sistema de notificación. 🌟

En el frontend, el componente React escucha los eventos enviados por el servidor a través de un Fuente del evento. A medida que se notifica a los empleados, sus detalles se actualizan dinámicamente en la interfaz de usuario sin necesidad de actualizar la página. Este enfoque proporciona una experiencia de usuario perfecta, similar a las actualizaciones en tiempo real que se ven en las aplicaciones web modernas, como resultados deportivos en vivo o notificaciones de redes sociales. Por ejemplo, los empleados del departamento de recursos humanos no verán las actualizaciones destinadas a Ventas, ya que el backend filtra con precisión los eventos según los criterios de asignación. Esta especificidad mejora tanto el rendimiento como la relevancia, creando un sistema centrado en el usuario. 🖥️

Envío de notificaciones masivas con eventos del lado del servidor (SSE) en NestJS

Esta solución demuestra un enfoque de backend para usar NestJS con Prisma y Server-Side Events (SSE) para operaciones masivas. Incluye una arquitectura basada en eventos y un sistema de colas.

// Backend: AllocateVoucherController
import { Controller, Post, Body, Sse, OnEvent } from '@nestjs/common';
import { AllocateVoucherService } from './allocate-voucher.service';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { Observable } from 'rxjs';
import { map, fromEvent } from 'rxjs';
@Controller('allocate-voucher')
export class AllocateVoucherController {
  constructor(
    private readonly allocateVoucherService: AllocateVoucherService,
    private readonly eventEmitter: EventEmitter2
  ) {}
  @Post()
  async create(@Body() createDto: any) {
    const result = await this.allocateVoucherService.create(createDto);
    return result;
  }
  @Sse('vouchered-employee')
  updatedEmployeeEvent(): Observable<MessageEvent> {
    return fromEvent(this.eventEmitter, 'after-added-voucher').pipe(
      map((data) => new MessageEvent('after-added-voucher', { data })),
    );
  }
}

Actualizaciones en tiempo real para inserciones masivas usando NestJS y React

Este ejemplo de interfaz utiliza React para escuchar eventos del lado del servidor y actualizar la interfaz de usuario dinámicamente a medida que se reciben datos. Garantiza que los empleados reciban notificaciones en tiempo real después de inserciones masivas.

// Frontend: React Component for SSE
import React, { useEffect, useState } from 'react';
const EmployeeUpdates = () => {
  const [employees, setEmployees] = useState([]);
  useEffect(() => {
    const eventSource = new EventSource('http://localhost:3000/allocate-voucher/vouchered-employee');
    eventSource.onmessage = (event) => {
      const newEmployee = JSON.parse(event.data);
      setEmployees((prev) => [...prev, newEmployee]);
    };
    return () => eventSource.close();
  }, []);
  return (
    <table>
      <thead>
        <tr><th>Name</th><th>Voucher</th></tr>
      </thead>
      <tbody>
        {employees.map((emp) => (
          <tr key={emp.id}><td>{emp.name}</td><td>{emp.voucher}</td></tr>
        ))}
      </tbody>
    </table>
  );
};
export default EmployeeUpdates;

Notificaciones de pruebas unitarias para operaciones de inserción masiva

Esta prueba de Jest garantiza que el mecanismo de notificación y emisión de eventos funcione correctamente en el backend para eventos del lado del servidor en NestJS.

// Jest Test: AllocateVoucherService
import { Test, TestingModule } from '@nestjs/testing';
import { AllocateVoucherService } from './allocate-voucher.service';
import { EventEmitter2 } from '@nestjs/event-emitter';
describe('AllocateVoucherService', () => {
  let service: AllocateVoucherService;
  let eventEmitter: EventEmitter2;
  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [AllocateVoucherService, EventEmitter2],
    }).compile();
    service = module.get(AllocateVoucherService);
    eventEmitter = module.get(EventEmitter2);
  });
  it('should emit after-allocate-voucher event', async () => {
    jest.spyOn(eventEmitter, 'emit');
    const result = await service.create({ someData: 'test' });
    expect(eventEmitter.emit).toHaveBeenCalledWith('after-allocate-voucher', result);
  });
});

Mejora de los sistemas en tiempo real con SSE en NestJS

Si bien hemos explorado la implementación de eventos del lado del servidor (SSE) para notificar a los empleados sobre la asignación de cupones, existe un caso de uso más amplio para SSE en sistemas en tiempo real. SSE brilla en escenarios donde los clientes necesitan mantenerse actualizados con los datos del servidor sin realizar encuestas constantemente. Por ejemplo, piense en una plataforma minorista en línea que rastrea las actualizaciones de inventario en vivo durante una venta flash. Con SSE, puede enviar actualizaciones de manera eficiente a todos los clientes conectados, asegurándose de que vean los niveles de existencias más recientes sin una carga innecesaria del servidor. Este enfoque garantiza la escalabilidad y al mismo tiempo mantiene la experiencia del usuario sin interrupciones. 🛒

Incorporar sistemas de colas avanzados como BullMQ, como hicimos con el vale de asignación cola, agrega solidez a las tareas de procesamiento de datos masivos. La cola garantiza que incluso si se reinicia el servidor, las tareas pendientes permanezcan intactas y el procesamiento se reanude. Además, se pueden configurar mecanismos de reintento, lo que garantiza que los trabajos fallidos (por ejemplo, debido a un tiempo de inactividad temporal de la base de datos) se reintenten automáticamente. Por ejemplo, si una asignación a 300 empleados en todos los departamentos encuentra un error temporal, la resistencia de la cola garantiza que no queden registros sin procesar, lo que agrega confiabilidad a su sistema.

Más allá de las notificaciones en tiempo real, SSE también puede complementar los servicios de correo electrónico para tareas que requieren resúmenes detallados. Después de que todas las notificaciones de cupones se envíen a través de SSE, el backend puede generar un informe de forma asincrónica y enviar un correo electrónico consolidado a los gerentes. Esta comunicación multicanal garantiza notificaciones inmediatas y seguimientos integrales, atendiendo a una amplia gama de preferencias de los usuarios. Dicha integración mejora la flexibilidad de su sistema, creando una experiencia de usuario integral. 📧

Preguntas frecuentes sobre SSE en NestJS

  1. ¿Cuáles son los beneficios de utilizar eventos del lado del servidor sobre WebSockets?
  2. SSE es más sencillo de implementar y utiliza HTTP, lo que lo hace compatible con firewalls. A diferencia de WebSockets, solo requiere una conexión unidireccional, lo que es eficiente para actualizaciones en tiempo real.
  3. ¿Puedo usar @Sse ¿Con múltiples puntos finales en un controlador?
  4. Sí, puedes definir múltiples @Sse puntos finales en el mismo controlador para servir diferentes flujos de datos a los clientes según necesidades específicas.
  5. ¿Cómo manejo los errores durante el procesamiento de la cola?
  6. Con BullMQ, puede definir opciones de reintento y utilizar detectores de eventos como @OnWorkerEvent('failed') para registrar errores y reprocesar trabajos si es necesario.
  7. ¿Prisma's createMany ¿El método admite reversiones de transacciones?
  8. Sí, Prisma. createMany se puede envolver en una transacción. Si alguna operación de la transacción falla, todas las operaciones se revierten para mantener la coherencia.
  9. ¿Qué sucede si el cliente se desconecta durante una transmisión SSE?
  10. El servidor deja de enviar actualizaciones una vez que detecta la desconexión. Puede implementar la lógica de reconexión en el cliente utilizando el EventSource API.
  11. ¿Se puede utilizar SSE para comunicación bidireccional?
  12. No, SSE es unidireccional (servidor a cliente). Para comunicación bidireccional, utilice WebSockets o transmisiones HTTP2.
  13. ¿Cómo aseguro los puntos finales de SSE en NestJS?
  14. Utilice guardias o middlewares, como @UseGuards, para hacer cumplir la autenticación y autorización para sus puntos finales de SSE.
  15. ¿Puede SSE funcionar con clientes que no son navegadores?
  16. Sí, cualquier cliente que admita HTTP y transmisión de eventos (por ejemplo, Node.js, cURL) puede consumir transmisiones SSE.
  17. ¿Cuál es la cantidad máxima de clientes que pueden conectarse a un punto final SSE?
  18. Esto depende de la configuración de su servidor y de los límites de recursos. El equilibrio de carga y la agrupación en clústeres pueden ayudar a escalar para admitir más clientes.
  19. ¿Es posible enviar datos JSON a través de SSE?
  20. Sí, puede serializar objetos en cadenas JSON y enviarlos usando new MessageEvent en NestJS.

Notificaciones efectivas en tiempo real en NestJS

Implementación de sistemas en tiempo real utilizando ESS en NestJS simplifica la comunicación entre el servidor y los clientes. Este método reduce la carga del servidor en comparación con el sondeo constante y permite una orientación precisa de las notificaciones. Por ejemplo, una herramienta de recursos humanos puede notificar a 200 empleados de Ventas sobre nuevos vales sin molestar a los demás. 🎯

Con herramientas como BullMQ y Prisma, esta configuración garantiza el procesamiento de tareas asíncrono y operaciones eficientes de la base de datos. La flexibilidad de la arquitectura basada en eventos la convierte en una solución escalable para diversos requisitos en tiempo real, lo que mejora la participación del usuario y la confiabilidad del sistema.

Fuentes y referencias
  1. Documentación detallada sobre Marco NestJS para crear aplicaciones escalables del lado del servidor.
  2. Guía de uso ToroMQ para una gestión sólida de la cola de trabajos en aplicaciones Node.js.
  3. Oficial Documentación de Prisma para operaciones de bases de datos y uso de ORM.
  4. Información sobre Eventos enviados por el servidor (SSE) para la comunicación cliente-servidor en tiempo real.
  5. Ejemplos prácticos de implementación de frontend del Documentación de ReactJS para construir interfaces de usuario interactivas.