Notificações sem esforço no NestJS usando eventos do lado do servidor para operações em massa

Temp mail SuperHeros
Notificações sem esforço no NestJS usando eventos do lado do servidor para operações em massa
Notificações sem esforço no NestJS usando eventos do lado do servidor para operações em massa

Entrega simplificada de notificações para operações de inserção em massa

Imagine que você está gerenciando um sistema onde centenas de funcionários recebem vouchers com base em vários critérios, como departamento, nota ou experiência. É uma tarefa colossal notificar cada funcionário de forma eficiente, sem causar gargalos no sistema. 🔔 Esse desafio se torna ainda mais assustador quando você pretende evitar as complexidades dos soquetes ou mecanismos de votação.

Nesses cenários, os eventos do lado do servidor (SSE) surgem como uma solução poderosa, porém simples. Ao aproveitar o SSE em seu aplicativo NestJS, você pode estabelecer um canal de comunicação em tempo real para notificar grupos específicos de funcionários com base em critérios dinâmicos. Por exemplo, quando os vouchers são atribuídos ao departamento de Vendas, apenas esses funcionários devem receber notificações, garantindo atualizações precisas e significativas.

Neste artigo, mergulharemos em um exemplo prático que demonstra como integrar o SSE em um processo de inserção em massa usando NestJS. Percorreremos todo o ciclo de vida, desde o acionamento de eventos no back-end até a escuta de atualizações no front-end, tudo isso mantendo um desempenho contínuo. 💼

Esteja você desenvolvendo uma ferramenta de RH ou um aplicativo financeiro, compreender esse fluxo de trabalho permitirá que você entregue notificações personalizadas em tempo real. Vamos desvendar a simplicidade do SSE e como ele pode elevar a experiência do usuário do seu aplicativo.

Comando Exemplo de uso
@Sse Um decorador NestJS usado para definir um endpoint de eventos do lado do servidor (SSE). Por exemplo, @Sse('funcionário com voucher') configura um endpoint para transmitir atualizações em tempo real para o cliente.
fromEvent Uma função do RxJS que converte um evento emitido por um Emissor de Evento em um fluxo observável. Por exemplo, fromEvent(this.eventEmitter, 'voucher pós-adicionado') escuta um evento específico.
Observable Um conceito central do RxJS usado para gerenciar fluxos de dados assíncronos. É essencial para lidar com eventos do lado do servidor no NestJS, como Observável<MessageEvent>.
@InjectQueue Um decorador NestJS que injeta uma instância de fila, útil para gerenciar o processamento de trabalhos com bibliotecas como Bull. Por exemplo, @InjectQueue('allotVoucher') fornece acesso à fila chamada 'allotVoucher'.
WorkerHost Uma classe base do BullMQ que permite definir processadores de trabalho personalizados no NestJS. Por exemplo, o AllotVoucherConsumidor extensão de classe TrabalhadorHost para lidar com trabalhos específicos.
@OnWorkerEvent Um decorador usado para escutar eventos específicos do ciclo de vida de um trabalho em fila. Por exemplo, @OnWorkerEvent('concluído') lida com o evento "concluído" de um trabalho.
createMany Um comando Prisma usado para inserir vários registros em um banco de dados de uma só vez. Por exemplo, prisma.employeeVoucher.createMany soma todos os vouchers dos funcionários em uma única operação.
EventSource Uma API JavaScript para receber eventos enviados pelo servidor (SSE) do back-end. Por exemplo, novo EventSource('http://localhost/vouchered-employee') estabelece uma conexão para streaming de dados.
add Um método das filas Bull para adicionar um novo trabalho à fila. Por exemplo, allotVoucherQueue.add('allot-voucher', jobData) agenda um trabalho para processamento.
@OnEvent Um decorador NestJS que escuta eventos específicos emitidos no aplicativo. Por exemplo, @OnEvent('após-alocação-voucher') aciona um método quando este evento é emitido.

Notificações eficientes com eventos e filas do lado do servidor

Os scripts fornecidos ilustram um sistema onde notificações em tempo real são enviadas aos funcionários após a inserção em massa de registros de vouchers no banco de dados. O processo começa no AlocarVoucherController, que expõe um endpoint para criar tarefas de alocação de vouchers. Quando uma tarefa é criada, ela emite um evento chamado voucher pós-alocação. Este evento é essencial para acionar as etapas subsequentes, garantindo que o sistema seja orientado a eventos e modular. Este design permite uma separação clara de preocupações, tornando o sistema mais sustentável e escalável. 🎯

Na camada de serviço, o AlocarVoucherService lida com a lógica para enfileirar tarefas usando BullMQ. Depois de receber o voucher pós-alocação evento, ele adiciona um trabalho à fila chamada voucher de atribuição. Essa fila permite o processamento assíncrono, garantindo que o sistema permaneça responsivo mesmo ao processar grandes conjuntos de dados. Por exemplo, se você alocar vouchers para 200 funcionários do departamento de Vendas, a fila garante que a operação não bloqueie outras solicitações. A configuração da fila inclui opções como removeOnComplete para manter o Redis limpo após a conclusão do trabalho.

Os trabalhos da fila são processados ​​pelo AllotVoucherConsumidor aula. Aqui é implementada a lógica de identificação dos funcionários relevantes e inserção de registros de vouchers no banco de dados. O comando Prisma criar muitos é usado para inserir registros em lote no funcionárioVoucher tabela, que é otimizada para desempenho. Após a conclusão da operação do banco de dados, outro evento é emitido para notificar os assinantes. Este evento garante que os funcionários só sejam notificados após o processamento bem-sucedido da inserção em massa, agregando confiabilidade ao sistema de notificação. 🌟

No frontend, o componente React escuta os eventos enviados pelo servidor através de um Fonte do Evento. À medida que os funcionários são notificados, seus detalhes são atualizados dinamicamente na IU sem a necessidade de atualização da página. Essa abordagem fornece uma experiência de usuário perfeita, semelhante às atualizações em tempo real vistas em aplicativos da web modernos, como resultados esportivos ao vivo ou notificações de mídia social. Por exemplo, os funcionários do departamento de RH não verão atualizações destinadas a Vendas, pois o back-end filtra eventos com precisão com base em critérios de alocação. Essa especificidade melhora o desempenho e a relevância, criando um sistema focado no usuário. 🖥️

Envio de notificações em massa com eventos do lado do servidor (SSE) no NestJS

Esta solução demonstra uma abordagem de back-end para usar NestJS com Prisma e Server-Side Events (SSE) para operações em massa. Inclui uma arquitetura orientada a eventos e um sistema de filas.

// 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 })),
    );
  }
}

Atualizações em tempo real para inserções em massa usando NestJS e React

Este exemplo de frontend usa React para ouvir eventos do lado do servidor e atualizar a UI dinamicamente conforme os dados são recebidos. Ele garante que os funcionários sejam notificados em tempo real após inserções em massa.

// 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;

Notificações de teste de unidade para operações de inserção em massa

Este teste Jest garante que o mecanismo de emissão e notificação de eventos funcione corretamente no back-end para eventos do lado do servidor no 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);
  });
});

Aprimorando sistemas em tempo real com SSE no NestJS

Embora tenhamos explorado a implementação de eventos do lado do servidor (SSE) para notificar os funcionários sobre alocações de vouchers, há um caso de uso mais amplo para SSE em sistemas em tempo real. O SSE se destaca em cenários onde os clientes precisam se manter atualizados com os dados do servidor sem fazer pesquisas constantes. Por exemplo, pense em uma plataforma de varejo on-line que rastreia atualizações de estoque em tempo real durante uma venda relâmpago. Usando o SSE, você pode enviar atualizações com eficiência para todos os clientes conectados, garantindo que eles visualizem os níveis de estoque mais recentes sem carga desnecessária do servidor. Essa abordagem garante escalabilidade enquanto mantém a experiência do usuário perfeita. 🛒

Incorporando sistemas avançados de filas como BullMQ, como fizemos com o voucher de atribuição fila, adiciona robustez às tarefas de processamento de dados em massa. A fila garante que, mesmo que ocorra uma reinicialização do servidor, as tarefas pendentes permaneçam intactas e o processamento seja retomado. Além disso, mecanismos de nova tentativa podem ser configurados, garantindo que trabalhos com falha (por exemplo, devido ao tempo de inatividade temporário do banco de dados) sejam repetidos automaticamente. Por exemplo, se uma alocação para 300 funcionários em vários departamentos encontrar um erro temporário, a resiliência da fila garante que nenhum registro fique sem processamento, adicionando confiabilidade ao seu sistema.

Além das notificações em tempo real, o SSE também pode complementar os serviços de e-mail para tarefas que exigem resumos detalhados. Depois que todas as notificações de vouchers forem enviadas via SSE, o backend pode gerar um relatório de forma assíncrona e enviar um e-mail consolidado aos gerentes. Esta comunicação multicanal garante notificações imediatas e acompanhamentos abrangentes, atendendo a uma ampla gama de preferências do usuário. Essa integração aumenta a flexibilidade do seu sistema, criando uma experiência de usuário completa. 📧

Perguntas frequentes sobre SSE no NestJS

  1. Quais são os benefícios de usar eventos do lado do servidor em vez de WebSockets?
  2. O SSE é mais simples de implementar e usa HTTP, tornando-o compatível com firewall. Ao contrário dos WebSockets, requer apenas uma única conexão unidirecional, que é eficiente para atualizações em tempo real.
  3. Posso usar @Sse com vários endpoints em um controlador?
  4. Sim, você pode definir vários @Sse endpoints no mesmo controlador para atender diferentes fluxos de dados aos clientes com base em necessidades específicas.
  5. Como lidar com erros durante o processamento da fila?
  6. Com BullMQ, você pode definir opções de nova tentativa e usar ouvintes de eventos como @OnWorkerEvent('failed') para registrar erros e reprocessar trabalhos, se necessário.
  7. O Prisma createMany método suporta reversões de transação?
  8. Sim, Prisma createMany pode ser envolvido em uma transação. Se alguma operação na transação falhar, todas as operações serão revertidas para fins de consistência.
  9. O que acontece se o cliente se desconectar durante um fluxo SSE?
  10. O servidor para de enviar atualizações assim que detecta a desconexão. Você pode implementar a lógica de reconexão no cliente usando o EventSource API.
  11. O SSE pode ser usado para comunicação bidirecional?
  12. Não, o SSE é unidirecional (servidor para cliente). Para comunicação bidirecional, use fluxos WebSockets ou HTTP2.
  13. Como faço para proteger endpoints SSE no NestJS?
  14. Use guardas ou middlewares, como @UseGuards, para impor autenticação e autorização para seus endpoints SSE.
  15. O SSE pode funcionar com clientes que não são navegadores?
  16. Sim, qualquer cliente que suporte HTTP e streaming de eventos (por exemplo, Node.js, cURL) pode consumir fluxos SSE.
  17. Qual é o número máximo de clientes que podem se conectar a um endpoint SSE?
  18. Isso depende da configuração do seu servidor e dos limites de recursos. O balanceamento de carga e o clustering podem ajudar a escalar para oferecer suporte a mais clientes.
  19. É possível enviar dados JSON por SSE?
  20. Sim, você pode serializar objetos em strings JSON e enviá-los usando new MessageEvent no NestJS.

Notificações eficazes em tempo real no NestJS

Implementando sistemas em tempo real usando SSE no NestJS simplifica a comunicação entre o servidor e os clientes. Este método reduz a carga do servidor em comparação com pesquisas constantes e permite direcionamento preciso para notificações. Por exemplo, uma ferramenta de RH pode notificar 200 funcionários de Vendas sobre novos vouchers sem atrapalhar os outros. 🎯

Com ferramentas como BullMQ e Prisma, essa configuração garante processamento assíncrono de tarefas e operações eficientes de banco de dados. A flexibilidade da arquitetura baseada em eventos a torna uma solução escalável para vários requisitos em tempo real, melhorando o envolvimento do usuário e a confiabilidade do sistema.

Fontes e Referências
  1. Documentação detalhada sobre Estrutura NestJS para construir aplicativos escaláveis ​​do lado do servidor.
  2. Guia sobre como usar TouroMQ para gerenciamento robusto de filas de trabalhos em aplicativos Node.js.
  3. Oficial Documentação Prisma para operações de banco de dados e uso de ORM.
  4. Informações sobre Eventos enviados pelo servidor (SSE) para comunicação cliente-servidor em tempo real.
  5. Exemplos práticos de implementação de frontend do Documentação ReactJS para construir interfaces de usuário interativas.