サーバーサイドイベントを使用した一括操作による NestJS での簡単な通知

サーバーサイドイベントを使用した一括操作による NestJS での簡単な通知
サーバーサイドイベントを使用した一括操作による NestJS での簡単な通知

一括挿入操作の合理化された通知配信

部門、グレード、経験などのさまざまな基準に基づいて何百人もの従業員に伝票が割り当てられるシステムを管理していると想像してください。システムにボトルネックを引き起こすことなく、各従業員に効率的に通知するのは大変な作業です。 🔔 ソケットやポーリング メカニズムの複雑さを回避しようとする場合、この課題はさらに困難になります。

このようなシナリオでは、サーバーサイド イベント (SSE) が強力かつ簡単なソリューションとして登場します。 NestJS アプリケーションで SSE を利用すると、リアルタイム通信チャネルを確立して、動的な基準に基づいて従業員の特定のグループに通知できます。たとえば、伝票が営業部門に割り当てられた場合、それらの従業員のみが通知を受信し、正確で有意義な更新が保証されるようにする必要があります。

この記事では、NestJS を使用して SSE を一括挿入プロセスに統合する方法を示す実践的な例について詳しく説明します。バックエンドでのイベントのトリガーからフロントエンドでの更新のリッスンまで、シームレスなパフォーマンスを維持しながら、ライフサイクルを順を追って説明します。 💼

HR ツールを開発している場合でも、財務アプリを開発している場合でも、このワークフローを理解すると、パーソナライズされた通知をリアルタイムで配信できるようになります。 SSE のシンプルさと、SSE がアプリケーションのユーザー エクスペリエンスをどのように向上させるかを紐解いてみましょう。

指示 使用例
@Sse サーバーサイド イベント (SSE) エンドポイントを定義するために使用される NestJS デコレーター。例えば、 @Sse('従業員証書') リアルタイム更新をクライアントにストリーミングするエンドポイントを設定します。
fromEvent によって発行されたイベントを変換する RxJS の関数 イベントエミッター 観測可能な流れに。 例えば、 fromEvent(this.eventEmitter, '追加後のクーポン') 特定のイベントをリッスンします。
Observable 非同期データ ストリームを管理するために使用される RxJS の中心的な概念。 これは、NestJS でサーバーサイド イベントを処理するために不可欠です。 観測可能<MessageEvent>
@InjectQueue キュー インスタンスを挿入する NestJS デコレータ。Bull などのライブラリを使用したジョブ処理の管理に役立ちます。 例えば、 @InjectQueue('allotVoucher') 「allotVoucher」という名前のキューへのアクセスを提供します。
WorkerHost NestJS でカスタム ジョブ プロセッサを定義できるようにする BullMQ の基本クラス。 たとえば、 割り当てクーポン消費者 クラスが拡張する ワーカーホスト 特定の仕事を処理するため。
@OnWorkerEvent キュー ジョブの特定のライフサイクル イベントをリッスンするために使用されるデコレータ。 例えば、 @OnWorkerEvent('完了') ジョブの「完了」イベントを処理します。
createMany 複数のレコードをデータベースに一度に挿入するために使用される Prisma コマンド。 例えば、 prisma.employeeVoucher.createMany すべての従業員の伝票を 1 回の操作で追加します。
EventSource バックエンドからサーバー送信イベント (SSE) を受信するための JavaScript API。 例えば、 new EventSource('http://localhost/vouchered-employee') ストリーミング データの接続を確立します。
add 新しいジョブをキューに追加する Bull キューのメソッド。 例えば、 allotVoucherQueue.add('allot-voucher', jobData) ジョブの処理をスケジュールします。
@OnEvent アプリケーション内で発行された特定のイベントをリッスンする NestJS デコレータ。 例えば、 @OnEvent('割り当て後のバウチャー') このイベントが発行されたときにメソッドをトリガーします。

サーバー側のイベントとキューによる効率的な通知

提供されているスクリプトは、データベースに伝票レコードを一括挿入した後にリアルタイム通知が従業員に送信されるシステムを示しています。プロセスは次から始まります。 バウチャーコントローラーの割り当て、伝票割り当てタスクを作成するためのエンドポイントを公開します。タスクが作成されると、という名前のイベントが発行されます。 割り当て後のバウチャー。このイベントは、後続のステップをトリガーするために不可欠であり、システムがイベント駆動型でモジュール型であることを保証します。この設計により、懸念事項を明確に分離できるため、システムの保守性と拡張性が向上します。 🎯

サービス層では、 バウチャーサービスの割り当て BullMQ を使用してタスクをキューに入れるためのロジックを処理します。を受け取った後、 割り当て後のバウチャー イベントが発生すると、ジョブがキューに追加されます。 割り当てバウチャー。このキューにより非同期処理が可能になり、大規模なデータセットを処理する場合でもシステムの応答性が確保されます。たとえば、営業部門の 200 人の従業員に伝票を割り当てる場合、キューによって操作が他のリクエストをブロックしないことが保証されます。キューの設定には次のようなオプションが含まれます 削除時完了 ジョブの完了後に Redis をクリーンな状態に保つため。

キュージョブは、 割り当てクーポン消費者 クラス。ここでは、関連する従業員を特定し、伝票レコードをデータベースに挿入するロジックが実装されています。プリズマコマンド たくさん作成 レコードをバッチに挿入するために使用されます。 従業員クーポン パフォーマンスのために最適化されたテーブル。データベース操作が完了すると、サブスクライバーに通知するために別のイベントが発行されます。このイベントにより、一括挿入が正常に処理された後にのみ従業員に通知が届くようになり、通知システムの信頼性が高まります。 🌟

フロントエンドでは、React コンポーネントがサーバーから送信されたイベントをリッスンします。 イベントソース。従業員に通知されると、ページを更新しなくても、従業員の詳細が UI で動的に更新されます。このアプローチは、スポーツのライブスコアやソーシャルメディア通知など、最新の Web アプリケーションで見られるリアルタイム更新に似た、シームレスなユーザー エクスペリエンスを提供します。たとえば、バックエンドが割り当て基準に基づいてイベントを正確にフィルタリングするため、人事部門の従業員には営業向けの更新が表示されません。この特異性により、パフォーマンスと関連性の両方が向上し、ユーザー中心のシステムが作成されます。 🖥️

NestJS のサーバーサイド イベント (SSE) を使用して通知を一括送信する

このソリューションは、Prisma およびサーバーサイド イベント (SSE) で NestJS を一括操作に使用するバックエンド アプローチを示します。これには、イベント駆動型のアーキテクチャとキュー システムが含まれています。

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

NestJS と React を使用した一括挿入のリアルタイム更新

このフロントエンドの例では、React を使用してサーバーサイド イベントをリッスンし、データの受信時に UI を動的に更新します。これにより、一括挿入後に従業員がリアルタイムで通知を受け取ることができます。

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

一括挿入操作の単体テスト通知

この Jest テストは、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);
  });
});

NestJS の SSE によるリアルタイム システムの強化

バウチャーの割り当てについて従業員に通知するためのサーバーサイド イベント (SSE) の実装を検討してきましたが、リアルタイム システムでは SSE のより広範な使用例があります。 SSE は、クライアントが常にポーリングを行わずにサーバー データを常に最新の状態に保つ必要があるシナリオで威力を発揮します。たとえば、フラッシュ セール中のリアルタイムの在庫更新を追跡するオンライン小売プラットフォームについて考えてみましょう。 SSE を使用すると、接続されているすべてのクライアントに更新を効率的にプッシュでき、サーバーに不必要な負荷をかけずに最新の在庫レベルを確実に表示できます。このアプローチにより、ユーザー エクスペリエンスをシームレスに保ちながら、スケーラビリティが確保されます。 🛒

の場合と同様に、BullMQ のような高度なキュー システムを組み込む 割り当てバウチャー キューを使用すると、大量のデータ処理タスクに堅牢性が追加されます。キューにより、サーバーが再起動された場合でも、保留中のタスクはそのまま残り、処理が再開されます。さらに、再試行メカニズムを構成して、(一時的なデータベースのダウンタイムなどにより) 失敗したジョブが自動的に再試行されるようにすることもできます。たとえば、複数の部門にわたる 300 人の従業員への割り当てで一時的なエラーが発生した場合、キューの回復力により未処理のレコードが残らないことが保証され、システムの信頼性が向上します。

SSE は、リアルタイムの通知だけでなく、詳細な概要が必要なタスクのために電子メール サービスを補完することもできます。すべてのバウチャー通知が SSE 経由で送信された後、バックエンドはレポートを非同期的に生成し、統合された電子メールをマネージャーに送信できます。このマルチチャネル通信により、即時通知と包括的なフォローアップの両方が保証され、幅広いユーザーの好みに対応します。このような統合によりシステムの柔軟性が向上し、バランスの取れたユーザー エクスペリエンスが実現します。 📧

NestJS の SSE に関するよくある質問

  1. WebSocket ではなくサーバーサイド イベントを使用する利点は何ですか?
  2. SSE は実装が簡単で、HTTP を使用するため、ファイアウォールとの親和性が高くなります。 WebSocket とは異なり、単一の一方向接続のみが必要なため、リアルタイム更新に効率的です。
  3. 使ってもいいですか @Sse コントローラー内に複数のエンドポイントがある場合
  4. はい、複数定義できます @Sse 同じコントローラー内のエンドポイントは、特定のニーズに基づいてクライアントに異なるデータ ストリームを提供します。
  5. キュー処理中のエラーはどのように処理すればよいですか?
  6. BullMQ を使用すると、再試行オプションを定義し、次のようなイベント リスナーを使用できます。 @OnWorkerEvent('failed') エラーをログに記録し、必要に応じてジョブを再処理します。
  7. プリズマはありますか? createMany メソッドはトランザクションのロールバックをサポートしますか?
  8. そう、プリズマさん createMany トランザクションにラップすることができます。トランザクション内のいずれかの操作が失敗した場合、一貫性を保つためにすべての操作がロールバックされます。
  9. SSE ストリーム中にクライアントが切断された場合はどうなりますか?
  10. サーバーは切断を検出すると、更新の送信を停止します。を使用してクライアントに再接続ロジックを実装できます。 EventSource API。
  11. SSE は双方向通信に使用できますか?
  12. いいえ、SSE は一方向 (サーバーからクライアント) です。双方向通信の場合は、WebSocket または HTTP2 ストリームを使用します。
  13. NestJS で SSE エンドポイントを保護するにはどうすればよいですか?
  14. 次のようなガードまたはミドルウェアを使用します。 @UseGuards、SSE エンドポイントの認証と認可を強制します。
  15. SSE はブラウザ以外のクライアントでも動作しますか?
  16. はい、HTTP およびイベント ストリーミングをサポートするクライアント (Node.js、cURL など) は、SSE ストリームを使用できます。
  17. SSE エンドポイントに接続できるクライアントの最大数はどれくらいですか?
  18. これは、サーバーの構成とリソース制限によって異なります。負荷分散とクラスタリングは、より多くのクライアントをサポートするための拡張に役立ちます。
  19. SSE 経由で JSON データを送信することはできますか?
  20. はい、オブジェクトを JSON 文字列にシリアル化し、次を使用して送信できます。 new MessageEvent NestJS で。

NestJS での効果的なリアルタイム通知

を使用してリアルタイム システムを実装する SSE NestJS では、サーバーとクライアント間の通信が簡素化されます。この方法では、定期的なポーリングと比較してサーバーの負荷が軽減され、通知の正確なターゲティングが可能になります。たとえば、HR ツールを使用すると、他の従業員に迷惑をかけることなく、営業部門の 200 人の従業員に新しい伝票について通知できます。 🎯

BullMQ や Prisma などのツールを使用すると、このセットアップにより、非同期タスク処理と効率的なデータベース操作が保証されます。イベントベースのアーキテクチャの柔軟性により、さまざまなリアルタイム要件に対応するスケーラブルなソリューションとなり、ユーザー エンゲージメントとシステムの信頼性が向上します。

出典と参考文献
  1. 詳細なドキュメント NestJS フレームワーク スケーラブルなサーバー側アプリケーションを構築するために。
  2. ご利用ガイド ブルMQ Node.js アプリケーションでの堅牢なジョブ キュー管理を実現します。
  3. 正式 プリズマのドキュメント データベース操作と ORM の使用について。
  4. に関する洞察 サーバー送信イベント (SSE) リアルタイムのクライアント/サーバー通信用。
  5. 実践的なフロントエンド実装例 ReactJS ドキュメント インタラクティブなユーザーインターフェイスを構築するため。