Notifications
Say a pet's status changes while its owner happens to be looking right at that pet's listing in their browser. Nothing about a normal request/response cycle tells their already-loaded page to update, and they're not about to poll for changes on the off chance something happened while they were looking. What actually needs to happen is for the server to push the update to that exact open connection, the moment it happens.
That's a different job from the event system on the previous page. Events are for services and background code reacting to each other. NotificationUtils is for pushing a message to one or more specific, currently-connected users: the kind of thing a WebSocket route forwards straight to a client.
class NotificationUtils {
constructor(redis: RedisClientType);
sendMessage(uids: string | string[], type: string, action: string, data: any): void;
}
sendMessage publishes a JSON payload ({type, action, data}) to a Redis channel named after each recipient's uid. On the receiving end, BasePushRoute is the concrete implementation of that idea: a WebSocket route that subscribes each connected client to its own uid channel (plus any others it has permission for) and forwards whatever's published there straight to the socket. A CLI-scaffolded project already has this wired up as PushRoute at /push; see Base Routes: Push for how connect and subscriptions work in detail.
Because its constructor takes a Redis connection directly rather than using property injection, construct it explicitly through the ObjectFactory with the connection you want it to publish through:
import {ObjectDecorators} from '@rapidrest/core';
import {NotificationUtils, DatabaseDecorators} from '@rapidrest/service-core';
import type {RedisClientType} from 'redis';
const {Inject} = ObjectDecorators;
const {Redis} = DatabaseDecorators;
export class PetService {
@Redis('cache')
private redis?: RedisClientType;
@Inject(ObjectFactory)
private objectFactory?: ObjectFactory;
async notifyOwner(ownerUid: string, pet: Pet) {
const notifications = await this.objectFactory?.newInstance(NotificationUtils, {args: [this.redis]});
notifications?.sendMessage(ownerUid, 'pet', 'updated', pet);
}
}
Related utilities
Two more utilities from @rapidrest/core round out the notification story: