Envoi rationalisé des notifications pour les opérations d'insertion en masse
Imaginez que vous gérez un système dans lequel des centaines d'employés se voient attribuer des bons en fonction de divers critères tels que le département, le grade ou l'expérience. C’est une tâche colossale que d’informer efficacement chaque employé sans provoquer de goulots d’étranglement dans le système. 🔔 Ce défi devient encore plus intimidant lorsque vous souhaitez éviter les complexités des sockets ou des mécanismes d'interrogation.
Dans de tels scénarios, les événements côté serveur (SSE) apparaissent comme une solution puissante mais simple. En tirant parti de SSE dans votre application NestJS, vous pouvez établir un canal de communication en temps réel pour informer des groupes spécifiques d'employés en fonction de critères dynamiques. Par exemple, lorsque des bons sont attribués au service commercial, seuls ces employés doivent recevoir des notifications, garantissant ainsi des mises à jour précises et significatives.
À travers cet article, nous allons plonger dans un exemple pratique qui montre comment intégrer SSE dans un processus d'insertion groupée à l'aide de NestJS. Nous parcourrons le cycle de vie, du déclenchement d'événements dans le backend à l'écoute des mises à jour sur le frontend, tout en maintenant des performances transparentes. 💼
Que vous développiez un outil RH ou une application financière, comprendre ce flux de travail vous permettra d'envoyer des notifications personnalisées en temps réel. Découvrons la simplicité de SSE et comment il peut améliorer l'expérience utilisateur de votre application.
Commande | Exemple d'utilisation |
---|---|
@Sse | Un décorateur NestJS utilisé pour définir un point de terminaison d'événements côté serveur (SSE). Par exemple, @Sse('employé-bon') configure un point de terminaison pour diffuser les mises à jour en temps réel au client. |
fromEvent | Une fonction de RxJS qui convertit un événement émis par un Émetteur d'événements dans un flux observable.
Par exemple, fromEvent (this.eventEmitter, 'bon ajouté après') écoute un événement spécifique. |
Observable | Un concept central de RxJS utilisé pour gérer les flux de données asynchrones.
Il est essentiel pour gérer les événements côté serveur dans NestJS, comme Observable<MessageEvent> . |
@InjectQueue | Un décorateur NestJS qui injecte une instance de file d'attente, utile pour gérer le traitement des tâches avec des bibliothèques comme Bull.
Par exemple, @InjectQueue('allotVoucher') donne accès à la file d'attente nommée 'allotVoucher'. |
WorkerHost | Une classe de base de BullMQ qui permet de définir des processeurs de tâches personnalisés dans NestJS.
Par exemple, le AllotVoucherConsommateur la classe s'étend Hôte de travail pour gérer des tâches spécifiques. |
@OnWorkerEvent | Un décorateur utilisé pour écouter les événements spécifiques du cycle de vie d’une tâche en file d’attente.
Par exemple, @OnWorkerEvent('terminé') gère l'événement "terminé" d'un travail. |
createMany | Une commande Prisma utilisée pour insérer plusieurs enregistrements dans une base de données à la fois.
Par exemple, prisma.employeeVoucher.createMany ajoute tous les bons des employés en une seule opération. |
EventSource | Une API JavaScript pour recevoir des événements envoyés par le serveur (SSE) depuis le backend.
Par exemple, nouveau EventSource('http://localhost/vouchered-employee') établit une connexion pour diffuser des données. |
add | Une méthode des files d'attente Bull pour ajouter un nouveau travail à la file d'attente.
Par exemple, allotVoucherQueue.add('allot-voucher', jobData) planifie un travail pour le traitement. |
@OnEvent | Un décorateur NestJS qui écoute les événements spécifiques émis au sein de l'application.
Par exemple, @OnEvent('après-allocation-bon') déclenche une méthode lorsque cet événement est émis. |
Notifications efficaces avec les événements et les files d'attente côté serveur
Les scripts fournis illustrent un système dans lequel des notifications en temps réel sont envoyées aux employés après l'insertion massive d'enregistrements de pièces justificatives dans la base de données. Le processus commence dans le AllocateVoucherController, qui expose un point de terminaison pour créer des tâches d'allocation de bons. Lorsqu'une tâche est créée, elle émet un événement nommé bon après allocation. Cet événement est essentiel pour déclencher les étapes suivantes, garantissant que le système est événementiel et modulaire. Cette conception permet une séparation claire des préoccupations, rendant le système plus maintenable et évolutif. 🎯
Dans la couche service, le AllouerVoucherService gère la logique de mise en file d'attente des tâches à l'aide de BullMQ. Après avoir reçu le bon après allocation événement, il ajoute un travail à la file d'attente nommé bon d'attribution. Cette file d'attente permet un traitement asynchrone, garantissant que le système reste réactif même lors du traitement de grands ensembles de données. Par exemple, si vous attribuez des bons à 200 collaborateurs du service Commercial, la file d'attente garantit que l'opération ne bloque pas d'autres demandes. La configuration de la file d'attente comprend des options telles que supprimerOnComplete pour garder Redis propre une fois le travail terminé.
Les travaux en file d'attente sont traités par le AllotVoucherConsommateur classe. Ici, la logique d'identification des employés concernés et d'insertion des enregistrements de pièces justificatives dans la base de données est mise en œuvre. La commande Prisma créerBeaucoup est utilisé pour insérer par lots des enregistrements dans le Chèque employé table, optimisée pour les performances. Une fois l'opération de base de données terminée, un autre événement est émis pour avertir les abonnés. Cet événement garantit que les employés ne sont informés qu'une fois que l'insertion groupée a été traitée avec succès, ajoutant ainsi de la fiabilité au système de notification. 🌟
Sur le frontend, le composant React écoute les événements envoyés par le serveur via un Source d'événement. Au fur et à mesure que les employés sont informés, leurs coordonnées sont mises à jour dynamiquement dans l'interface utilisateur sans nécessiter d'actualisation de la page. Cette approche offre une expérience utilisateur transparente, semblable aux mises à jour en temps réel vues dans les applications Web modernes telles que les résultats sportifs en direct ou les notifications sur les réseaux sociaux. Par exemple, les employés du service RH ne verront pas les mises à jour destinées aux ventes, car le backend filtre précisément les événements en fonction de critères d'attribution. Cette spécificité améliore à la fois les performances et la pertinence, créant un système axé sur l'utilisateur. 🖥️
Envoi de notifications en masse avec des événements côté serveur (SSE) dans NestJS
Cette solution démontre une approche backend pour utiliser NestJS avec Prisma et Server-Side Events (SSE) pour les opérations en masse. Il comprend une architecture événementielle et un système de file d'attente.
// 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 })),
);
}
}
Mises à jour en temps réel pour les insertions groupées à l'aide de NestJS et React
Cet exemple d'interface utilise React pour écouter les événements côté serveur et mettre à jour l'interface utilisateur de manière dynamique à mesure que les données sont reçues. Il garantit que les employés sont informés en temps réel après des insertions groupées.
// 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;
Notifications de tests unitaires pour les opérations d’insertion en masse
Ce test Jest garantit que le mécanisme d'émission et de notification d'événements fonctionne correctement dans le backend pour les événements côté serveur dans 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);
});
});
Améliorer les systèmes en temps réel avec SSE dans NestJS
Bien que nous ayons exploré la mise en œuvre d'événements côté serveur (SSE) pour informer les employés de l'attribution de bons, il existe un cas d'utilisation plus large du SSE dans les systèmes en temps réel. SSE brille dans les scénarios où les clients doivent rester informés des données du serveur sans interrogation constante. Par exemple, pensez à une plateforme de vente au détail en ligne qui suit les mises à jour des stocks en direct lors d'une vente flash. Grâce à SSE, vous pouvez envoyer efficacement des mises à jour à tous les clients connectés, en vous assurant qu'ils visualisent les derniers niveaux de stock sans charge inutile du serveur. Cette approche garantit l’évolutivité tout en gardant l’expérience utilisateur transparente. 🛒
Intégrer des systèmes de file d'attente avancés comme BullMQ, comme nous l'avons fait avec le bon d'attribution file d'attente, ajoute de la robustesse aux tâches de traitement de données en masse. La file d'attente garantit que même en cas de redémarrage du serveur, les tâches en attente restent intactes et le traitement reprend. De plus, des mécanismes de nouvelle tentative peuvent être configurés, garantissant que les tâches ayant échoué (par exemple, en raison d'un temps d'arrêt temporaire de la base de données) soient automatiquement réessayées. Par exemple, si une allocation à 300 employés dans tous les départements rencontre une erreur temporaire, la résilience de la file d'attente garantit qu'aucun enregistrement n'est laissé sans traitement, ajoutant ainsi de la fiabilité à votre système.
Au-delà des notifications en temps réel, SSE peut également compléter les services de messagerie pour les tâches nécessitant des résumés détaillés. Une fois toutes les notifications de bons envoyées via SSE, le backend peut générer un rapport de manière asynchrone et envoyer un e-mail consolidé aux responsables. Cette communication multicanal garantit à la fois des notifications immédiates et un suivi complet, répondant à un large éventail de préférences des utilisateurs. Une telle intégration améliore la flexibilité de votre système, créant une expérience utilisateur complète. 📧
Foire aux questions sur SSE dans NestJS
- Quels sont les avantages de l'utilisation des événements côté serveur par rapport aux WebSockets ?
- SSE est plus simple à mettre en œuvre et utilise HTTP, ce qui le rend compatible avec les pare-feu. Contrairement aux WebSockets, il ne nécessite qu’une seule connexion unidirectionnelle, efficace pour les mises à jour en temps réel.
- Puis-je utiliser @Sse avec plusieurs points de terminaison dans un contrôleur ?
- Oui, vous pouvez définir plusieurs @Sse points de terminaison dans le même contrôleur pour servir différents flux de données aux clients en fonction de besoins spécifiques.
- Comment gérer les erreurs lors du traitement de la file d’attente ?
- Avec BullMQ, vous pouvez définir des options de nouvelle tentative et utiliser des écouteurs d'événements comme @OnWorkerEvent('failed') pour enregistrer les erreurs et retraiter les tâches si nécessaire.
- Est-ce que Prisma createMany la méthode prend-elle en charge les annulations de transactions ?
- Oui, celui de Prisma createMany peut être enveloppé dans une transaction. Si une opération de la transaction échoue, toutes les opérations sont annulées par souci de cohérence.
- Que se passe-t-il si le client se déconnecte pendant un flux SSE ?
- Le serveur arrête d'envoyer des mises à jour une fois qu'il détecte la déconnexion. Vous pouvez implémenter une logique de reconnexion sur le client à l'aide du EventSource API.
- SSE peut-il être utilisé pour une communication bidirectionnelle ?
- Non, SSE est unidirectionnel (serveur vers client). Pour une communication bidirectionnelle, utilisez des flux WebSockets ou HTTP2.
- Comment sécuriser les points de terminaison SSE dans NestJS ?
- Utilisez des gardes ou des middlewares, comme @UseGuards, pour appliquer l'authentification et l'autorisation pour vos points de terminaison SSE.
- SSE peut-il fonctionner avec des clients autres que des navigateurs ?
- Oui, tout client prenant en charge HTTP et le streaming d'événements (par exemple, Node.js, cURL) peut consommer des flux SSE.
- Quel est le nombre maximum de clients pouvant se connecter à un point de terminaison SSE ?
- Cela dépend de la configuration de votre serveur et des limites de ressources. L'équilibrage de charge et le clustering peuvent aider à évoluer pour prendre en charge davantage de clients.
- Est-il possible d'envoyer des données JSON via SSE ?
- Oui, vous pouvez sérialiser des objets en chaînes JSON et les envoyer en utilisant new MessageEvent dans NestJS.
Notifications efficaces en temps réel dans NestJS
Implémentation de systèmes temps réel en utilisant ESS dans NestJS simplifie la communication entre le serveur et les clients. Cette méthode réduit la charge du serveur par rapport à une interrogation constante et permet un ciblage précis des notifications. Par exemple, un outil RH peut informer 200 employés du service commercial de l'arrivée de nouveaux bons d'achat sans perturber les autres. 🎯
Avec des outils comme BullMQ et Prisma, cette configuration garantit un traitement des tâches asynchrone et des opérations de base de données efficaces. La flexibilité de l'architecture basée sur les événements en fait une solution évolutive pour diverses exigences en temps réel, améliorant l'engagement des utilisateurs et la fiabilité du système.
Sources et références
- Documentation détaillée sur Cadre NestJS pour créer des applications côté serveur évolutives.
- Guide d'utilisation BullMQ pour une gestion robuste des files d'attente de tâches dans les applications Node.js.
- Officiel Documentation Prisma pour les opérations de base de données et l’utilisation d’ORM.
- Aperçus sur Événements envoyés par le serveur (SSE) pour la communication client-serveur en temps réel.
- Exemples pratiques de mise en œuvre du frontend tirés du Documentation ReactJS pour créer des interfaces utilisateur interactives.